Which constructor invokes this semantics?

This is the line construct:

string s {"Hello world!"}; 

And the string class has the following constructor, which I think can be related to:

From char pointer / array:

 string (const char* s); 

From the initializer_list file:

 string (initializer_list<char> il); 

At first, I thought it would call initializer_list because the parameters are bound. Then I saw that initializer_list takes a char argument, but it was a string.

Then I understand that {""} can be implicitly converted to char[] , so it can call the first constructor ... In this case, this is a pair of parentheses automatically added around the list (for example, like ({""}) ) ?

So which constructor does it really call?


How about this:

 double d1 (100); double d2 {100}; 
They are the same?

Suppose the line also has a constructor, such as string(initializer_list<string>) , and which it will call?

+4
source share
2 answers
 string(const char*) 

The syntax {} does not necessarily mean std::initializer_list .

+5
source

In C ++ 11, curly braces {} are used to uniformly initialize. Any object that can be initialized can be initialized with curly braces. Preference is given to constructors that accept initializer_list<T> , therefore, if initialization of the italic bracket can correspond to more than one constructor, and one of them accepts initializer_list , which will be selected. However, if the initializer_list constructors do not match, other constructors are also considered.

For instance:

 vector<int> two_elems{5,10}; // A vector containing two elements vector<int> five_elems(5,10); // A vector containing five elements vector<int> five_elems_also{10,10,10,10,10}; // Equivalent to the above 

In your example, you initialize string with char const[13] . This will match initializer_list<char const*> if string has such a constructor but does not match initializer_list<char> . Thus, this parameter is mapped to other constructors, and a constructor accepting char const* is the best match.

Note that because of the ambiguity, it is best not to initialize containers (e.g. vector , set , list or even string )) using parenthesis initialization unless you intend to use initializer_list constructors. For example, there is no way to call the vector<size_t> constructor, which takes size_t, T using the brace-initialization function, since this argument list will also match the initializer_list constructor. As another example:

 vector<char const*> vec_of_strs{ 5, 0 }; // Creates a vector holding *5* nullptrs vector<unsigned> vec_of_nums{ 5, 0 }; // Creates a vector holding *2* numbers 

It is not immediately obvious that the two lines above cause very different constructors, and if the type of one was changed to another during maintenance (or the code that occurred in the template), programmers may be very surprised by the sudden behavior of the change.

+8
source

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


All Articles