Initializing / Assigning a Structure Using Braces

I defined the structure as follows:

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

But I have problems when it comes to understanding the various ways of initializing / assigning values ​​to my members. For instance:

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

All these options work with -std = C ++ 11. However, on the older compiler with -std = C ++ 0x, initialization / assignment brackets do not work. Is usign binding to bad practice? Which options are better to get used to?

+4
source share
1 answer

In C ++ 11, all of them are legal. If you know that you will work with a compiler compatible with C ++ 11 (at least as far as the initialization of the list is concerned), I would say that it is preferable to use the binding syntax. This is the future and unambiguous.

Here is a detailed analysis of the individual statements:

 float3 vec3D = {1.0, 1.0, 1.0}; 

Copy-list-initialization. Strictly speaking, this creates a temporary float3 , invoking its constructor with three parameters, then initializes vec3D using the move constructor (or copy constructor if there is no ctor move), and finally destroys the temporary.

In practice, the temporary operation of creating and moving / copying will be eliminated by any non-localized compiler, so there is no inefficiency. However, note that this requires the move / copy constructor to be available. For example, you cannot initialize an immovable, non-copyable class, for example.

 float3 vec3D2 {1.0, 1.0, 1.0}; float3 vec3D3 (1.0, 1.0, 1.0); 

Both of them directly initialize vec3D2 , invoking its constructor with three parameters. I would say that the bracket is the optimal syntax because it is unique. In this particular case, it does not matter, but sometimes using parentheses can lead to (most) annoying analysis 1 .

 vec3D = {2.0, 2.0, 2.0}; vec3D = float3 (2.0, 2.0, 2.0); 

They are 100% identical if vec3D is equal to float3 . Both create a temporary float3 object using its constructor with three parameters, pass this object to the vec3D move (or copy) vec3D , and then destroy the temporary ones.

I would say that the bracket is better, because this is the future proof. If you rename the class later, the bracket will continue to work as it is, while the name chaage is required in parentheses. In addition, if you change the type of vec3D , the bracket will still create an object of type vec3D , and the second will continue to create and assign the object float3 . It is impossible to say universally, but I would say that the previous behavior is usually preferable.


1 An example of this would be:

 float3 x(float3()); // a function //vs. float3 y{float3{}}; // a variable 
+2
source

Source: https://habr.com/ru/post/985921/


All Articles