- 我可以
optional从constexpr函数中返回一个吗? - 为什么?
- 如果是,它是如何工作的?
我对 和 都boost::optional感兴趣std::optional。他们的行为是否相同?
optional从constexpr函数中返回一个吗?我对 和 都boost::optional感兴趣std::optional。他们的行为是否相同?
boost::optional不能由constexpr函数返回。或者至少,文档不对此提供任何保证。
但是,std::optional正如接受的 C++14 提案所定义的,可以由constexpr函数返回。但前提是的类型参数optional是可以简单破坏的。
这使得析构函数std::optional在这些情况下变得微不足道。在这一点上,销毁对象没有困难,所以没有什么可以阻止std::optional成为文字类型。
提案对此非常明确。如果T很容易破坏,那么 的大多数构造函数optional将是constexpr,并且optional<T>将是文字类型。因此,它可以在constexpr函数中创建。
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