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