如何实现std :: optional的副本构造函数? [英] How to implement std::optional's copy constructor?

查看:207
本文介绍了如何实现std :: optional的副本构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现 std::optional ,但是遇到了复制构造函数之一.

这是我的实现示意图:

#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构造函数没有空的正文:

The problem is that the compiler complains that optional's constexpr constructor does not have an empty body:

$ 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).

I'm not sure how to initialize optional::m_data otherwise, and I haven't been able to find a reference implementation the web (boost::optional apparently does not use constexpr).

有什么建议吗?

推荐答案

在C ++ 11中,标记为constexpr的函数和构造函数的作用非常有限.对于构造函数,除static_asserttypedef使用声明使用指令外,它基本上不能包含其他任何内容,从而排除了在内部使用operator=进行调用的情况.构造函数的主体.

In C++11 functions and constructors marked as constexpr are very limited in what they can do. In the case of constructors, it cannot contain basically anything other than static_assert, typedef or using declarations or using directives, which rules out calling operator= inside the body of the constructor.

这篇关于如何实现std :: optional的副本构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆