在C ++ 14中:
对于任何整数或枚举类型T
以及任何表达式expr
:
之间是否存在差异:
struct S { T t { expr }; };
和
struct S { T t = { expr }; };
更新
我到[dcl.init.list]p3b5
说:
如果初始化列表具有E类型的单个元素且T不是引用类型或其引用类型与E引用相关,则从该元素初始化对象或引用。
我认为此引用适用于 direct-list-initialization 和 copy-list-initialization 。
所以我认为答案是肯定的,没有区别。
答案 0 :(得分:5)
如果您查看direct initialization和copy initialization个引用,您会发现相同的字词:
如果T是非类类型,则在必要时使用标准转换将其他值转换为cv非限定版本的T
所以应该没有区别。这些初始化的区别仅适用于类类型:复制初始化 不考虑explicit
构造函数和explicit
用户定义的转换运算符直接初始化。积分和枚举类型都没有。
修改强>
@ᐅ Johannes Schaub - litb ᐊ answered a relative question to this one(只有括号,而不是大括号),他引用8.5/14
的措辞相似(强调我的):
初始化的形式(使用括号或=)通常是 无关紧要,但在初始化程序或实体时确实很重要 正在初始化有一个类类型;见下文。如果实体是 initialized没有类类型,表达式列表在一个 带括号的初始值设定项应为单个表达式。
我也找不到标准中的{}
对应物。我希望这足以支持没有区别答案。
答案 1 :(得分:1)
struct S {T t { expr };};
是一个非静态数据成员初始值设定项
不使用等号。struct S{T t = { expr };};
是一个非静态数据成员初始值设定项
使用等号。第一种情况是直接列表初始化,而第二种情况是复制列表初始化。
direct-list-initialization 和 copy-list-initialization 之间的区别在于第一种情况两者显式和非显式考虑构造函数,而对于第二个唯一可以调用非显式构造函数。
澄清一下,请考虑以下示例:
struct Foo {
int i;
explicit Foo(int i_) : i(i_) {}
};
struct Bar {
Foo f {1};
};
在此示例中,Foo
有一个explicit
构造函数,Bar
直接初始化其f
类型的成员Foo
。示例代码编译得很好,因为直接初始化会考虑explicit
和non-explicit
构造函数。
现在我们通过转换非静态数据成员初始化程序而不使用等号来改变示例,这是使用等号对非静态数据成员初始化程序进行直接列表初始化的情况,这是一个copy-list-initialization的案例。
struct Foo {
int i;
explicit Foo(int i_) : i(i_) {}
};
struct Bar {
Foo f = {1};
};
现在上面的例子没有编译并发出错误:
错误:选择的构造函数在复制初始化中是显式的
这是预期的,因为正如在copy-list-initialization中已经提到的那样,只能调用非显式构造函数。
现在对于枚举器和其他整数类型,上面显示的差异不会适用(即,不涉及构造函数)。因此,这两个陈述(即[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};
};
这两个例子也编译得很好。