Noe*_*oel 5 c++ initialization variable-assignment
我已经定义了一个结构如下:
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) {}
};
Run Code Online (Sandbox Code Playgroud)
但是,在理解为其成员初始化/赋值的不同方法时,我遇到了麻烦.例如:
//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);
Run Code Online (Sandbox Code Playgroud)
所有这些选项都适用于-std = c ++ 11.但是在使用-std = c ++ 0x的旧编译器上,braces初始化/赋值不起作用.使用是否是一种不好的做法?哪个选项更适合习惯?
在C++11中,所有这些都是合法的。如果您知道您将使用符合 C++11 的编译器(至少就列表初始化而言),我认为最好使用大括号语法。它是面向未来且明确的。
下面对各个说法进行详细分析:
float3 vec3D = {1.0, 1.0, 1.0};
Run Code Online (Sandbox Code Playgroud)
复制列表初始化。严格按照书本,这float3通过调用其 3 参数构造函数来创建临时文件,然后vec3D使用移动构造函数(或复制构造函数,如果没有可用的移动构造函数)进行初始化,最后销毁临时文件。
实际上,临时创建和移动/复制操作将被任何未损坏的编译器省略,因此不存在效率低下的情况。但是,请注意,它要求移动/复制构造函数可访问。例如,您不能像这样初始化不可移动、不可复制的类。
float3 vec3D2 {1.0, 1.0, 1.0};
float3 vec3D3 (1.0, 1.0, 1.0);
Run Code Online (Sandbox Code Playgroud)
这两个都vec3D2通过调用其 3 参数构造函数来直接初始化。我想说大括号是最佳语法,因为它是明确的。在这种特殊情况下,这并不重要,但有时,使用括号可能会导致(最)令人烦恼的解析1。
vec3D = {2.0, 2.0, 2.0};
vec3D = float3 (2.0, 2.0, 2.0);
Run Code Online (Sandbox Code Playgroud)
只要 的类型vec3D是,它们就 100% 相同float3。两者都使用其 3 参数构造函数创建一个临时float3对象,将该对象传递给 的移动(或复制)赋值运算符vec3D,然后销毁该临时对象。
我认为支架更好,因为它是面向未来的。如果您稍后重命名该类,大括号类将继续按原样工作,而括号类将需要名称更改。另外,如果更改 的类型vec3D,大括号中的一个仍将创建vec3D's 类型的对象,而第二个大括号将继续从对象创建和分配float3。不可能一概而论,但我想说前一种行为通常是首选。
1例如:
float3 x(float3()); // a function
//vs.
float3 y{float3{}}; // a variable
Run Code Online (Sandbox Code Playgroud)