【问题标题】:How to implement std::optional's copy constructor?如何实现 std::optional 的复制构造函数?
【发布时间】:2014-01-21 03:04:39
【问题描述】:

我正在实施std::optional,但遇到了其中一个copy constructors 的障碍。

这是我的实现草图:

#include <type_traits>

template<typename T>
class optional
{
  public:
    constexpr optional()
      : m_is_engaged(false)
    {}

    constexpr optional(const optional &other)
      : m_is_engaged(false)
    {
      operator=(other);
    }

    constexpr optional &operator=(const optional &other)
    {
      if(other.m_is_engaged)
      {
        return operator=(*other);
      }
      else if(m_is_engaged)
      {
        // destroy the contained object
        (**this).~T();
        m_is_engaged = false;
      }

      return *this;
    }

    template<typename U>
    optional &operator=(U &&value)
    {
      if(m_is_engaged)
      {
        operator*() = value;
      }
      else
      {
        new(operator->()) T(value);
        m_is_engaged = true;
      }

      return *this;
    }

    T* operator->()
    {
      return reinterpret_cast<T*>(&m_data);
    }

    T &operator*()
    {
      return *operator->();
    }

  private:
    bool m_is_engaged;
    typename std::aligned_storage<sizeof(T),alignof(T)>::type m_data;
};

#include <tuple>

int main()
{
  optional<std::tuple<float, float, float>> opt;

  opt = std::make_tuple(1.f, 2.f, 3.f);

  return 0;
}

问题是编译器抱怨optional的constexpr构造函数没有空体:

$ g++ -std=c++11 test.cpp 
test.cpp: In copy constructor ‘constexpr optional<T>::optional(const optional<T>&)’:
test.cpp:15:5: error: constexpr constructor does not have empty body
     }
     ^

我不知道如何初始化optional::m_data,否则我无法在网络上找到参考实现(boost::optional 显然不使用constexpr)。

有什么建议吗?

【问题讨论】:

  • 您是否注意到链接中的移动和复制 ctor 未标记为 constexpr?
  • 深入了解proposal,他们也谈论它:It is still possible to make the destructor trivial for T's which provide a trivial destructor themselves, and we know an efficient implementation of such optional&lt;T&gt; with compile-time interface — **except for copy constructor and move constructor** — is possible.。

标签: c++ constexpr boost-optional


【解决方案1】:

在 C++11 中,标记为 constexpr 的函数和构造函数的功能非常有限。对于构造函数,它基本上不能包含除static_assert、typedef 或 using 声明 或 using 指令 之外的任何内容,这排除了在内部调用 operator=构造函数的主体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 2019-10-11
    • 2018-09-20
    • 1970-01-01
    • 2021-11-29
    • 2012-08-24
    相关资源
    最近更新 更多