一段时间以来,人们已经能够在 GCC 中使用“指定初始化程序”:
struct CC{
double a_;
double b_;
};
CC cc{.a_ = 1., .b_ = 2.}; assert(cc.a_ == 1. and cc.b_ == 2.); // ok
CC cc{.bla = 0., .bli = 0.}; // compile error
但是,当我添加构造函数时,标签将被忽略。
struct CC{
double a_;
double b_;
CC(double a, double b) : a_{a}, b_{b}{}
};
CC cc{.a_ = 1., .b_ = 2.}; assert(cc.a_ == 1. and cc.b_ == 2.); // ok
CC cc{.b_ = 2., .a_ = 1.}; // compiles but labels don't matter only the order, confusing
CC cc{.bla = 2., .bli = 1.}; // compiles but labels don't matter, confusing
换句话说,带有构造函数的初始化语法使标签的行为就像注释一样!,这可能会让人非常困惑,但最重要的是,它非常奇怪。
我用 gcc 8.1 -std=c++2a
无意中发现了这一点。
这是预期的行为吗?
引用:https://en.cppreference.com/w/cpp/language/aggregate_initialization
EDIT 2022:现在编译器支持 -std=c++20
行为是正确的。所有接受 -std=c++20
(10.1 及更高版本)的 GCC 版本也接受上述代码或在应该时给出错误。
最佳答案
编译器不应忽略指定初始化程序的标签。所有这三个带有构造函数的示例都应该是病式的。
由于 C++20 指定初始化程序功能与 GCC 的 C 样式指定初始化程序之间存在冲突,您可能会出现此行为,因为 GCC 只是将它们提供给您,您正在隐式访问它们。如果 GCC 是正确的 C++20 兼容的,一旦你给类型一个构造函数,它就不再是一个聚合,因此指定的初始化器用法将是错误的。
基本上,这是编译器默认为您提供的非 C++ 标准行为导致的驱动程序错误。很有可能,如果您关闭此功能,您将在这些情况下得到正确的编译器错误。
关于c++ - 构造函数干扰成员变量指定初始化器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52282288/