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

Can I return an optional from a constexpr function?

本文关键字:一个 可选项 constexpr 函数 返回 我可以      更新时间:2023-10-16
  • 我可以从constexpr函数返回optional
  • 为什么
  • 如果是,它是如何工作的

我对boost::optionalstd::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