c++ - 带大括号的结构初始化/赋值

标签 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) {}
};

但在理解为其成员初始化/赋值的不同方式时,我遇到了麻烦。例如:

//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/

相关文章:

c++ - 错误代码Visual Studio错误:c2059 strange syntax error

c++ - 为什么不能为此 C++ 代码示例打印两次 deconstruct?

c - 在 C 中,为什么不能在声明后将字符串分配给 char 数组?

c++ - 为什么标准首选的圆括号初始化 `make_<something>`?

arrays - perl6 数组赋值 : pointer or copy?

c -/etc/passwd的C程序

c++ - 如何编写最佳页面替换算法?

c++ - DAWG 与基数树?

c - 指向结构的指针数组,调试时只有 SIGSEGV

c - 合并排序在 C 与 O(N*log[N]) 运行时