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

VS切换至C++20后,初始化列表转结构体失败的编译问题

为什么显式默认拷贝构造函数会导致C++20中聚合初始化失败?

你的代码问题根源在于C++20修改了聚合类型的判定规则,具体细节如下:

问题核心

在C++17及更早版本中,显式默认的拷贝构造函数(foo(const foo&) = default;)不会影响foo作为聚合类型的判定,所以foo{'a'}会触发聚合初始化,直接给成员a赋值。

但C++20的标准里,任何用户声明的构造函数(包括显式默认或删除的特殊成员函数)都会让类型不再属于聚合类型。你的foo因为声明了拷贝构造函数,不再是聚合类型,此时foo{'a'}这种列表初始化会尝试寻找匹配的构造函数——而你的foo既没有接受char的构造函数,也没有能适配初始化列表的构造函数,因此编译器报错"无法从初始化列表转换为foo"。

解决办法

根据你的需求,可以选择以下几种方案:

  1. 删除显式默认的拷贝构造函数
    如果你没有特殊需求(比如需要抑制移动构造或其他场景),编译器会自动生成默认的拷贝构造函数,此时foo恢复为聚合类型,foo{'a'}的聚合初始化就能正常工作。

  2. 添加显式构造函数支持列表初始化
    如果你必须保留显式默认的拷贝构造函数,可以手动添加一个接受char的构造函数,让初始化列表能匹配上:

    struct foo {
        foo(const foo&) = default;
        foo(char c) : a(c) {} // 显式构造函数适配char类型
        char a;
    };
    
  3. 使用指定成员的聚合初始化(仅当类型为聚合时可用)
    若删除拷贝构造函数让foo回到聚合类型,也可以用更清晰的成员指定语法完成初始化:

    foo f{.a = 'a'};
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:06:24