我遇到了这种奇怪的行为,我找不到很好的解释。
下面的代码会在 c++20 之前成功编译,只有在explicit使用时才会失败。
struct Square {
int area = 10;
Square() = default; // only if this is explicit will the compile fail
Square(const Square& other) = delete;
Square(Square&& other) = delete;
Square& operator =(Square&& square) = delete;
Square& operator =(const Square& square) = delete;
};
int main() {
Square s = {
.area = 10
};
}
Run Code Online (Sandbox Code Playgroud)
这本身就很奇怪,但是将编译器转换为 c++20 会使上面的代码失败并显示这些错误消息
海湾合作委员会
无法转换大括号括起来的初始化列表
铛
没有用于初始化“Square”的匹配构造函数
问题:
为什么它在 c++20 之前编译成功,除非explicit?换句话说,会发生什么隐式转换来实现这一点?
c++20 中的哪些更改导致此代码无法编译?
为什么c++20之前就编译成功了...
C++20 之前的程序格式不正确。
C++20 之前的语言中不存在指定的初始化程序。它是由于语言扩展而编译的。
c++20 中发生了什么变化导致它不再编译?
该程序在 C++20 中仍然格式错误。
C++20 中的语言引入了指定初始化程序,并且规则似乎与语言扩展的规则略有不同。相关规则为(来自最新草案):
[dcl.init.list] T 类型的对象或引用的列表初始化定义如下:
如果花括号初始化列表包含指定初始化列表,则 T 应是聚合类。...
...
[dcl.init.aggr] 聚合是一个数组或一个类 ([class]),其中
没有用户声明或继承的构造函数([class.ctor]),
...
正如NathanOliver所解释的,C++20 之前的语言扩展的行为差异可能与聚合定义的变化有关