具有聚合类型的 std::make_Optional 在 C++20 中合法吗?

cpt*_*ssa 2 c++ language-lawyer aggregate-initialization c++20

假设有以下代码片段:

#include <optional>

struct MyStruct
{
//    MyStruct(int a) : a(a) {}
    int a;
};

int main()
{
   std::optional<MyStruct> ms1 = std::make_optional<MyStruct>(1);  

   std::optional<MyStruct> ms2{2};

   std::optional<MyStruct> ms3;
   ms3.emplace(3);

   std::optional<MyStruct> ms4(std::in_place, 4);
}
Run Code Online (Sandbox Code Playgroud)

这按预期使用 c++20 和 gcc 11.2 工作,所有这四种创建方法都在 clang 上编译失败(编译器资源管理器链接

为了使其与 clang 一起工作,我需要取消注释构造函数。

我的主要问题是:clang 还是 gcc 哪个编译器是正确的?

后续问题:如果 clang 是正确的,是否有任何方法可以在可选中创建没有构造函数的结构,而不将结构复制到其中,例如std::optional<MyStruct> ms{MyStruct{3}}

康桓瑋*_*康桓瑋 7

我的主要问题是:clang 还是 gcc 哪个编译器是正确的?

海湾合作委员会是正确的。由于 Clang 尚未实现P0960,这将导致以下断言失败并禁用 的optional构造函数:

static_assert(std::is_constructible_v<MyStruct, int>);
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以创建一个没有可选构造函数的结构,而不将结构复制到其中?

在Clang完成P0960之前,我想是没有办法的。但由于是一个右值,因此MyStruct{3}它将移至optional