You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20中对聚合类型使用std::make_optional是否合法?GCC和Clang谁正确

问题1:GCC和Clang哪一个符合C++20标准要求?

GCC的实现符合C20标准,Clang属于未完全实现标准特性导致的编译失败。
这个差异来源于C
20引入的P0960R3提案(允许使用圆括号初始化聚合类型):该提案正式允许聚合类型用圆括号完成初始化,同时修改了std::is_constructible的判定规则,只要参数列表可以用于聚合初始化对应类型,std::is_constructible_v<T, Args...>就会返回true。
而std::optional的emplace、std::in_place构造、std::make_optional这类API的约束条件恰好是std::is_constructible_v<T, Args...>,因此给出的代码在符合C++20标准的实现中应该正常编译,Clang是因为还未完整落地P0960R3的所有规则才会报错。

问题2:适配Clang的零开销写入方案

首先需要明确:你提到的std::optional<MyStruct> ms{MyStruct{3}}这类写法在C17及以上版本中不存在额外的拷贝开销:C17引入了强制复制消除规则,MyStruct{3}作为纯右值会直接在std::optional的内部存储上构造,不会产生临时对象的拷贝、移动操作,哪怕关闭优化也不会有额外开销。
如果想要更明确的原位构造写法,也可以选择以下方案:

  • 调用emplace传递临时对象,同样享受强制复制消除:
    std::optional<MyStruct> ms3;
    ms3.emplace(MyStruct{3});
    
  • 结合std::in_place和列表初始化:
    std::optional<MyStruct> ms4(std::in_place, MyStruct{4});
    

如果你的Clang版本支持C++20指派初始化,也可以写为更清晰的形式:

std::optional<MyStruct> ms(std::in_place, {.a = 3});

内容的提问来源于stack exchange,提问作者cptFracassa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 04:06:03