C++ 为什么gcc接受指定的初始化而没有效果,并且生成的聚合以某种方式作为参数传递给类构造函数

C++ 为什么gcc接受指定的初始化而没有效果,并且生成的聚合以某种方式作为参数传递给类构造函数,c++,gcc,c++20,designated-initializer,C++,Gcc,C++20,Designated Initializer,好的,我们有这个代码: #include <iostream> using namespace std; class A{ public: A(double b, int g) { cout << "b = " << b << ", g = " << g << endl; } }; int main() { A a = {.g = 5

好的,我们有这个代码:

#include <iostream>
using namespace std;

class A{
    public:
    A(double b, int g) {
        cout << "b = " << b << ", g = " << g << endl;
    }
};

int main()
{
    A a = {.g = 5.0, .j = 10};      // output: b = 5, g = 10 
    A b = {.b = 5.0, .g = 10};      // output: b = 5, g = 10
    A bb = { 4.0, 20 };             // output: b = 4, g = 20
    A c = {.g = 5.0, .b = 10, 9};   // error: could not convert ‘{5.0e+0, 10, 9}’ from ‘<brace-enclosed initializer list>’ to ‘A’
    A d = {.g = 5, .b = 10.0};      // error: narrowing conversion of ‘1.0e+1’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
    A e = {.b = 10.0};              // error: could not convert ‘{1.0e+1}’ from ‘<brace-enclosed initializer list>’ to ‘A’
    return 0;
}
Cppreference about仅显示类字段的命名初始化情况,而不显示构造函数参数。聚合初始化和列表初始化示例也没有在构造函数中显示这种特性

正如警告中所述,这种情况可能被视为C++20特性,但是查看,以及cppreference.com中建议的特性,只会为聚合类型指定初始化,而不会像我的情况那样通过构造函数参数进行初始化

问题:

它为什么以及如何工作? 是ISO C++ 20还是GNU C++特性? 应说明1。是否被视为gcc编译器静默bug?
具有用户定义构造函数的类不是聚合类。如果使用指定的初始化器,则该类应为骨料。您的程序在非聚合上使用指定的初始化器,因此它是一个格式错误的程序。允许编译器不编译它,并且需要编译器诊断问题

此外,指定的初始化者应指定骨料的一个成员。您的程序没有在初始化器中命名成员,因此它的格式不正确

是ISO C++ 20还是GNU C++特性?< /P> 指定的初始化器通常是C++20的标准特性,也是C++20之前的GNU特性

初始化指定初始值的非聚集不是标准C++特征。无论它是一个bug还是一个特性,它都是特定于实现的东西

应说明1。是否被视为gcc编译器静默bug

缺少诊断信息违反了标准


这似乎在trunk中已经修复,所有使用指定初始值设定项的情况在GCC中都是错误的:最新发布的10.2版仍然没有出现错误。

具有用户定义构造函数的类不是聚合类。如果使用指定的初始化器,则该类应为骨料。您的程序在非聚合上使用指定的初始化器,因此它是一个格式错误的程序。允许编译器不编译它,并且需要编译器诊断问题

此外,指定的初始化者应指定骨料的一个成员。您的程序没有在初始化器中命名成员,因此它的格式不正确

是ISO C++ 20还是GNU C++特性?< /P> 指定的初始化器通常是C++20的标准特性,也是C++20之前的GNU特性

初始化指定初始值的非聚集不是标准C++特征。无论它是一个bug还是一个特性,它都是特定于实现的东西

应说明1。是否被视为gcc编译器静默bug

缺少诊断信息违反了标准


这似乎已在主干中修复,所有使用指定初始值设定项的情况在GCC中都是错误的:最新发布的10.2版仍然复制了缺少错误的情况。

以及适用于bb={4.0,20}行的规则是什么?A仍然是非聚合的,并且值被传递给构造函数。@A的列表初始化。从C++11开始,它就被定义为非聚合。只是出于兴趣,在gcc中找到了commit,它修复了问题,以及什么规则适用于行A bb={4.0,20}?A仍然是非聚合的,并且值被传递给构造函数。@A的列表初始化。从C++11开始,它就被定义为非聚合。只是出于兴趣,在gcc中找到了commit,修复了这个问题
error: no matching constructor for initialization of 'A'
note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'double' for 1st argument
note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided