- 我可以
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