- 我能从constexpr函数中返回
optional
吗? - 为什么?
- 如果可以,它是如何工作的?
我对boost::optional
和std::optional
都很感兴趣。它们的行为是否相同?
optional
吗?我对boost::optional
和std::optional
都很感兴趣。它们的行为是否相同?
boost::optional
不能由 constexpr
函数返回。至少文档没有这方面的保证。
然而,根据已接受的 C++14 提案所定义的 std::optional
可以由 constexpr
函数返回。但是,仅当 optional
的类型参数是平凡可销毁的时才可以。
这允许在这些情况下 std::optional
的析构函数是平凡的。此时,销毁对象没有任何困难,所以没有任何东西阻止 std::optional
成为文字类型。
提案对此非常明确。 如果 T
是平凡可销毁的,则大多数 optional
的构造函数将是 constexpr
的,并且 optional<T>
将是一个文字类型。因此,它可以在 constexpr
函数中创建。
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
std::optional
,你肯定忘记了 c++1y 标签。 - sehestd::optional
和boost::optional
之间有什么区别,使得这种情况成立?在C++11中,boost::optional
是否会有可能实现这一点? - gnzlbg