【发布时间】:2021-01-05 13:37:48
【问题描述】:
存储在std::optional<T> 实例中的对象是否保证在放置new 时就地初始化?这是我对大多数实现的期望,但是,我也可以想象以下实现:
/* pseudocode */
template<typename T> class optional {
T object;
bool has_value;
};
在这种情况下,当构造一个不包含值的std::optional<T> 时,必须调用T 的默认构造函数。
是不是保证不是这样,即使T确实有默认构造函数,也不会被调用?
我能在 cppreference 上找到与内存管理相关的所有内容如下:“如果一个可选项包含一个值,则该值保证作为可选对象占用空间的一部分进行分配,即不会进行动态内存分配地点。” (https://en.cppreference.com/w/cpp/utility/optional)
但是,我上面的“实现”也符合这个要求。
【问题讨论】:
-
您链接的文档指出
T的唯一要求是dectructible,所以我假设是这样。除非使用placement new,否则这是不可能的。 -
它在任何时候都不是用 new 构造的。默认情况下它不构造对象。实现通常只是在类中保留额外的空间以供将来可能的构建。
-
@ALX23z 问题指定了新的位置,这也是这种初始化在幕后工作的方式。否则,您将如何在您提到的在类中保留的额外空间中构造一个对象?
-
@super 哦...错过了“放置”部分。我也相信它可以通过联合来完成,而不需要放置新的。
-
@ALX23z 可能用于聚合,但如果您在联合中使用具有用户定义的构造函数和析构函数的类,您通常也需要使用placement new 在活动成员之间切换。所以最后你不会有太多收获。
标签: c++ c++17 language-lawyer std c++20