我最近发现你不能同时在类初始化和初始化列表中。 以下代码失败:
struct s
{
int i=0;
};
int main() {
s s1; //s1.i = 0
//s s2={42}; //fails
return 0;
}
如果我删除了类初始化,初始化列表工作正常!
有人可以解释我为什么不允许这样的事情?
答案 0 :(得分:7)
实际上这在C ++ 14中是允许的。
struct s
{
int i=0;
};
int main() {
s s1;
s s2 = {42}; // succeeds
}
您的编译器可能没有在C ++ 14中实现新规则。然而,clang的最新版本接受了这一点,并且在C ++ 14模式下做了正确的事情。
当向C ++ 11添加了类内初始化时,它被指定为阻止类成为聚合。之所以这样做,是因为当时聚合概念与PoD类型密切相关,而PoD类型需要是可以轻易构建的。具有类内初始化意味着类型不再是简单的可构造的。然而,从那以后,这两个概念变得更加独立,因此对于C ++ 14来说,一个反对该决定的简短提议被接受了。
答案 1 :(得分:4)
这个初始化:
s s1 = { 42 };
要求s
是聚合,或者它有一个有效的构造函数,例如int或std::initializer_list
。
在声明点添加成员初始化时,您将类s
呈现为非聚合,因此您不能再使用聚合初始化。
您可以通过添加构造函数为非聚合使用相同的初始化语法:
struct s
{
s(int i) : i(i) {}
int i=0;
};
我相信这个限制已经放宽了C ++ 14。
有关详细信息,请参阅What are aggregates...。