-
struct S {T t { expr };}; 是一个非静态数据成员初始化器
不使用等号。
-
struct S{T t = { expr };}; 是一个非静态数据成员初始化器
使用等号。
第一种情况是direct-list-initialization,而第二种情况是copy-list-initialization。
direct-list-initialization 和 copy-list-initialization 的区别在于,对于第一种情况 both 显式和非显式考虑构造函数,而对于第二个仅可以调用非显式构造函数。
为了澄清,请考虑以下示例:
struct Foo {
int i;
explicit Foo(int i_) : i(i_) {}
};
struct Bar {
Foo f {1};
};
Live Demo
在此示例中,Foo 有一个 explicit 构造函数,Bar 直接初始化其类型为 Foo 的成员 f。示例代码编译良好,因为对于直接初始化,explicit 和 non-explicit 构造函数都被考虑在内。
现在我们通过将不使用等号的非静态数据成员初始化器转换为使用等号的非静态数据成员初始化器的情况,即直接列表初始化的情况来改变示例,即复制列表初始化的一个案例。
struct Foo {
int i;
explicit Foo(int i_) : i(i_) {}
};
struct Bar {
Foo f = {1};
};
Live Demo
现在上面的例子没有编译并发出错误:
错误:选择的构造函数在复制初始化中是显式的
这是意料之中的,因为正如在复制列表初始化中已经提到的那样,只有非显式构造函数可以调用。
现在对于枚举器和其他整数类型,上面显示的差异将不适用(即不涉及构造函数)。因此,这两个语句(即 [1] 和 [2])是等价的。
但为了完整起见,让我们考虑以下示例:
enum class Foo {A, B, C};
struct Bar {
Foo f{Foo::A};
};
和
enum class Foo {A, B, C};
struct Bar {
Foo f = {Foo::A};
};
这两个例子都编译得很好。
还请考虑以下示例:
struct Bar {
int i {1};
};
和
struct Bar {
int i = {1};
};
这两个例子都编译得很好。