std::optional 不应该在执行 emplacement 构造函数时包含其值吗?

Shouldn't std::optional contain its value while the emplacing constructor is executing?

提问人:Tobi 提问时间:4/29/2021 最后编辑:EnlicoTobi 更新时间:4/30/2021 访问量:266

问:

在实际代码中,构造函数可能非常复杂,因此 of a 可以查询可选本身的状态。当这种情况发生时,它通常会更复杂一些,但这里有一个(人为的)最小示例:emplacestd::optional

#include <iostream>
#include <optional>

struct Thing {
    Thing();
};

std::optional<Thing> othing;

Thing::Thing() {
    std::cout << othing.has_value() << std::endl;
}

int main() {
    othing.emplace();
}

对于所有三个主要的标准库实现,这会产生 .换言之,在执行 emplacement 构造函数期间,可选的构造函数不包含值false

从实现的角度来看,这意味着首先就地构造值,然后设置一些簿记变量。在 MSVClibc++ 和 libstdc++ 中确实如此。

现在,该标准的相关部分如下:

[...]当 的实例包含值时,表示在可选对象的存储中分配了类型为 T 的对象(称为可选对象的包含值)。optional<T>

有趣的是,这没有使用所包含对象的明确定义的生存期(我想是因为这可以从外部强制结束,例如),而是在存储中分配的术语。该标准通常在动态内存的上下文中谈论分配,在这些情况下,分配显然发生在构造之前othing->~Thing()

因此,我认为上述标准库实现不合规,应在构建开始之前设置簿记变量。

在这个假设下,仍然存在一个问题:实现是否比标准更好,而不是后者需要修复或澄清? 我不这么认为:在构建大型对象期间,访问已经初始化的子对象是完全有效和常见的,因此对于包含在可选中的对象来说,这应该也是可能的。

那么我的考虑对吗?还是我对其中分配的术语的解释不正确?是否有反对我的观点的论据,即什么是正确的事情™?

C++ 17 语言律师 C++-标准库 std可选

评论

4赞 underscore_d 4/29/2021
我不想被告知它包含尚未或未完全构造的值。这在我看来是完全正确的。您可以提交一篇论文以获得更好的法律措辞!
7赞 T.C. 4/29/2021
cplusplus.github.io/LWG/issue2414。除了未定义(或者可能是实现定义为未定义)之外,这不可能是任何东西。
0赞 Tobi 4/29/2021
@T.C.我认为这已经是答案了

答: 暂无答案