我可以从constexpr函数返回一个可选项吗?

gnz*_*lbg 10 c++ boost std constexpr boost-optional

  • 我可以optionalconstexpr函数返回吗?
  • 为什么?
  • 如果是,它是如何工作的?

我感兴趣的两个boost::optionalstd::optional.他们的行为是否相同?

Nic*_*las 10

boost::optional不能由constexpr函数返回.或者至少,文档不保证这一点.

但是,std::optional如接受的C++ 14提议所定义,可以constexpr函数返回.但只有当它的类型论证optional是可以轻易破坏的时候.

这允许析构函数std::optional在这些情况下是微不足道的.在这一点上,破坏对象没有任何困难,所以没有什么能阻止std::optional它成为文字类型.

该提议非常明确.如果T是简单的可破坏的,那么大多数构造函数optional将是constexpr,并且optional<T>将是文字类型.因此,它可以在constexpr函数中创建.


eca*_*mur 6

Boost.Optional不支持constexpr,主要是因为它是在C++ 11发布之前编写的.

当前的提案std::optional不支持constexpr,只要值类型T是平凡的破坏.它的工作原理 constexpr是允许构造者加入工会(7.1.5p4); 编译器跟踪初始化哪个union成员,确保在编译时捕获访问脱离可选值的未定义行为:

struct dummy_t {};
template <class T>
union optional_storage {
  static_assert( is_trivially_destructible<T>::value, "" );
  dummy_t dummy_;
  T       value_;
  constexpr optional_storage(): dummy_{} {}  // disengaged
  constexpr optional_storage(T const& v): value_{v} {}  // engaged
  ~optional_storage() = default;
};
Run Code Online (Sandbox Code Playgroud)

值类型必须是简单的可破坏的,因为constexpr它只适用于文字类型,它们本身必须有一个简单的析构函数.

例如,写作:

constexpr optional_storage<int> o{};
constexpr int i = o.value_;
Run Code Online (Sandbox Code Playgroud)

gcc给出错误:

error: accessing ‘optional_storage<int>::value_’ member instead of initialized 
‘optional_storage<int>::dummy_’ member in constant expression
Run Code Online (Sandbox Code Playgroud)