我定义了一个结构如下:
struct float3 {
float x;
float y;
float z;
float3 () : x(0), y(0), z(0) {}
float3 (float a, float b, float c) : x(a), y(b), z(c) {}
};
但在理解为其成员初始化/赋值的不同方式时,我遇到了麻烦。例如:
//Initialization
float3 3Dvec = {1.0, 1.0, 1.0};
float3 3Dvec2 {1.0, 1.0, 1.0};
float3 3Dvec3 (1.0, 1.0, 1.0);
//Assignment
3Dvec = {2.0, 2.0, 2.0};
3Dvec = float3 (2.0, 2.0, 2.0);
所有这些选项都适用于 -std=c++11。但是,在带有 -std=c++0x 的旧编译器上,大括号初始化/赋值不起作用。使用大括号是一种不好的做法吗?哪个选项更容易习惯?
最佳答案
在 C++11 中,所有这些都是合法的。如果您知道您将使用符合 C++11 的编译器(至少就列表初始化而言),我会说最好使用大括号语法。它面向 future 且明确无误。
以下是对个别陈述的详 segmentation 析:
float3 vec3D = {1.0, 1.0, 1.0};
复制列表初始化。严格按照书上的规定,这会创建一个临时的 float3
通过调用其三参数构造函数,然后初始化 vec3D
通过使用移动构造函数(或复制构造函数,如果没有可用的移动构造函数),最后销毁临时对象。
在实践中,临时创建和移动/复制操作将被任何未损坏的编译器省略,因此没有低效率。 但是, 请注意,它需要移动/复制构造函数才能访问。例如,您不能像这样初始化不可移动、不可复制的类。
float3 vec3D2 {1.0, 1.0, 1.0};
float3 vec3D3 (1.0, 1.0, 1.0);
这两个都直接初始化vec3D2
通过调用其 3 参数构造函数。我会说大括号是最佳语法,因为它是明确的。在这种特殊情况下,没关系,但有时,使用括号会导致 (most) vexing parse 1.
vec3D = {2.0, 2.0, 2.0};
vec3D = float3 (2.0, 2.0, 2.0);
这些是 100% 相同的,只要 vec3D
的类型相同是float3
.两者都创建一个临时的 float3
使用其 3 参数构造函数的对象,将该对象传递给 vec3D
的移动(或复制)赋值运算符, 然后销毁临时的。
我会说大括号更好,因为它是面向 future 的。如果您稍后重命名类,大括号将继续按原样工作,而括号将需要一个名称 chaage。此外,如果您更改 vec3D
的类型, 大括号仍然会创建 vec3D
的对象的类型,而第二个将继续从 float3
创建和分配目的。不可能一概而论,但我会说通常首选前一种行为。
1 例如:
float3 x(float3()); // a function
//vs.
float3 y{float3{}}; // a variable
关于c++ - 带大括号的结构初始化/赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24138140/