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

11
  • 我能从constexpr函数中返回optional吗?
  • 为什么?
  • 如果可以,它是如何工作的?

我对boost::optionalstd::optional都很感兴趣。它们的行为是否相同?


1
使用 std::optional,你肯定忘记了 c++1y 标签 - sehe
@sehe 感谢您的编辑!std::optionalboost::optional之间有什么区别,使得这种情况成立?在C++11中,boost::optional是否会有可能实现这一点? - gnzlbg
2个回答

11

boost::optional 不能由 constexpr 函数返回。至少文档没有这方面的保证。

然而,根据已接受的 C++14 提案所定义的 std::optional 可以由 constexpr 函数返回。但是,仅当 optional 的类型参数是平凡可销毁的时才可以。

这允许在这些情况下 std::optional 的析构函数是平凡的。此时,销毁对象没有任何困难,所以没有任何东西阻止 std::optional 成为文字类型。

提案对此非常明确。 如果 T 是平凡可销毁的,则大多数 optional 的构造函数将是 constexpr 的,并且 optional<T> 将是一个文字类型。因此,它可以在 constexpr 函数中创建。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接