在C++11中,所有这些都是合法的。如果您知道您将使用兼容 C++11 的编译器(至少就列表初始化而言),我认为最好使用大括号语法。它是面向未来且明确的。
下面对各个说法进行详细分析:
float3 vec3D = {1.0, 1.0, 1.0};
复制列表初始化。严格按照书本,这会创建一个临时的float3
通过调用其 3 参数构造函数,然后初始化vec3D
通过使用移动构造函数(或复制构造函数,如果没有可用的移动构造函数),最后销毁临时对象。
实际上,临时创建和移动/复制操作将被任何未损坏的编译器省略,因此不存在效率低下的情况。However,请注意,它要求移动/复制构造函数可访问。例如,您不能像这样初始化不可移动、不可复制的类。
float3 vec3D2 {1.0, 1.0, 1.0};
float3 vec3D3 (1.0, 1.0, 1.0);
Both of these directly initialise vec3D2
by calling its 3-parameter constructor. I'd say the brace one is the optimal syntax, because it's unambiguous. In this particular case, it does not matter, but sometimes, using parentheses can lead to a (most) vexing parse1.
vec3D = {2.0, 2.0, 2.0};
vec3D = float3 (2.0, 2.0, 2.0);
只要类型相同,它们都是 100% 相同的vec3D
is float3
。两者都会创建一个临时的float3
使用其 3 参数构造函数的对象,将该对象传递给 的移动(或复制)赋值运算符vec3D
,然后销毁临时的。
我认为支架更好,因为它是面向未来的。如果您稍后重命名该类,大括号类将继续按原样工作,而括号类将需要名称更改。另外,如果您更改类型vec3D
,大括号仍然会创建一个对象vec3D
的类型,而第二个将继续从 a 进行创建和分配float3
目的。不可能一概而论,但我想说前一种行为通常是首选。
1 An example of that would be:
float3 x(float3()); // a function
//vs.
float3 y{float3{}}; // a variable