在阅读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);

在常量表达式中,您不能执行几项操作,其中包括newreinterpret_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/

10-15 04:31