在阅读GCC的std::optional
实现时,我注意到了一些有趣的东西。我知道boost::optional
的实现如下:
template <typename T>
class optional {
// ...
private:
bool has_value_;
aligned_storage<T, /* ... */> storage_;
}
但是随后libstdc++和libc++(以及Abseil)都实现了自己的
optional
类型,如下所示:template <typename T>
class optional {
// ...
private:
struct empty_byte {};
union {
empty_byte empty_;
T value_;
};
bool has_value_;
}
在我看来,它们在功能上是相同的,但是使用它们相对于其他有什么好处吗? (除了后者中明显缺少新的位置,这确实很好。)
最佳答案
这不仅是“真正的好”,而且对于真正重要的功能至关重要,即:
constexpr std::optional<int> o(42);
在常量表达式中,您不能执行几项操作,其中包括
new
和reinterpret_cast
。如果您使用optional
实现了aligned_storage
,则需要使用new
创建对象,并使用reinterpret_cast
将其取回,这将阻止optional
成为constexpr
友好对象。使用
union
实现,您就不会遇到此问题,因此您可以在optional
编程中使用constexpr
(甚至在fix for trivial copyability所谈论的Nicol之前,已经要求 optional
可用作constexpr
)。关于c++ - std::optional实现为union vs char []/aligned_storage,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52338255/