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

我对 和 都boost::optional感兴趣std::optional。他们的行为是否相同?

4

2 回答 2

11

boost::optional不能由constexpr函数返回。或者至少,文档不对此提供任何保证

但是,std::optional正如接受的 C++14 提案所定义的,可以constexpr函数返回。但前提的类型参数optional是可以简单破坏的。

这使得析构函数std::optional在这些情况下变得微不足道。在这一点上,销毁对象没有困难,所以没有什么可以阻止std::optional成为文字类型。

提案对此非常明确。如果T很容易破坏,那么 的大多数构造函数optional将是constexpr,并且optional<T>将是文字类型。因此,它可以在constexpr函数中创建。

于 2013-05-07T13:32:34.513 回答
6

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

当前的提议std::optional确实支持constexpr,只要值类型T是可简单破坏的。它之所以有效,是因为 constexpr联合(7.1.5p4)允许构造函数;编译器跟踪初始化了哪个联合成员,确保在编译时捕获未定义的访问未使用的可选值的行为:

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

值类型必须是可平凡破坏的,因为constexpr仅对文字类型有用,而文字类型本身必须具有平凡的析构函数。

例如,写作:

constexpr optional_storage<int> o{};
constexpr int i = o.value_;

gcc 给出错误:

error: accessing ‘optional_storage<int>::value_’ member instead of initialized 
‘optional_storage<int>::dummy_’ member in constant expression
于 2013-05-07T13:48:32.833 回答