Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
219 views
in Technique[技术] by (71.8m points)

c++ - What are the differences between C-like, constructor, and uniform initialization?

To the best of my knowledge, there are three ways to initialize a variable in C++.

int x = 0;    // C-like initialization
int x (0);    // Constructor initialization
int x {0};    // Uniform initialization

The uniform initialization was brought on for C++11 to provide a more uniform syntax for initializing different types of variables, which required different syntax in C++03.

What are the differences between C-like, constructor, and uniform initialization? And should I always use the uniform initialization?

question from:https://stackoverflow.com/questions/65866467/what-is-the-difference-between-using-and-in-this-constructors-initialize

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, I would recommend looking at the following talk by Herb Sutter, in which he gives some recommendations about the subject. The brace-initialization discussion starts at around 23:00.

When you are talking about primitive data types, all 3 yield the same result. I personally prefer sticking with the old int x = 0 syntax, but it comes down to personal preference.

For class types, brace initialization and old-school constructor initialization are not completely interchangeable. For example:

vector<int> v (100); // Creates a 100-element vector
vector<int> v {100}; // Creates a 1-element vector, holding the value 100.

This is because std::vector has a constructor that explicitly defines std::initializer_list as its only argument. Keep in mind that

auto var = {1, 2};

creates a std::initializer_list, with var as its identifier.

The thing about initializer lists is that they provide consistency that is a welcome change from what was available beforehand. For example, if you were to initialize an array in C++, you would use:

int arr[] = {1, 2, 3, 4};

But, if you wanted to initialize a vector<int> with the same elements, you either had to:

  1. Initialize the above arr first and then pass arr and arr + 4
  2. Create the vector and push_back() the elements individually or in a loop.

With C++11, you could just use

vector<int> v = {1, 2, 3, 4}; // Same syntax. Nice! Note that the = is optional

Another instance in which brace initialization is helpful is that it provides a workaround to C++'s most vexing parse. From the talk, assume that we have two classes, origin and extents, whose instances can be passed to construct another object of type rectangle. The following statement:

rectangle w(origin(), extents());

doesn't allow you to create a rectangle object using origin and extents temporaries, because that statement is parsed as a function declaration. Tsk tsk. So normally, you would have to do:

origin  o;
extents e;
rectangle w(o, e);

With brace initialization, you can create them on the fly, and

rectangle w {origin(), extents()};

will work as intended, i.e. passed to the constructor which is overloaded with an origin object as it's first argument and an extents object as the second.

The rule is for objects, use brace initialiation unless you have a reason not to.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...