0

を実装std::optionalしていますが、そのコピー コンストラクターの 1 つに問題が発生しました。

これが私の実装のスケッチです。

#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;
}

問題は、コンパイラーがoptionalconstexprコンストラクターに空の本体がないことを訴えることです。

$ 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また、Web の参照実装を見つけることができませんでした (boost::optional明らかに を使用していませんconstexpr)。

助言がありますか?

4

1 に答える 1