Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

are there any plans in C++ standard to address inconsistency of initializer list constructors?

initializer list constructors in C++ often cause trouble; for example

using std::vector;
using std::string;
vector<string> v{3}; // vector of three empty strings
vector<int> u{3}; // vector of one element with value 3

(Just to clarify, I mean <int> constructor is an initializer list constructor, while the <string> one is not.)

The int case matches the initializer list constructor, while the string case doesn't. This is somewhat ugly, and often causes trouble. It was also noted in an early chapter (item 7) in Scott Meyers' Effective Modern C++, and he describes it as a somewhat unpleasant part of the standard, that whenever an initializer list constructor is available, compilers will jump through hoops to try to match it, giving it priority over every single other constructor.

Of course, the int case can be easily fixed by changing u{3} to u(3), but that's not the point.

Is this desirable behavior? Has there been any discussion or plans by the C++ standard committee to fix this type of ambiguity / unpleasantness? One example would be requiring initializer list constructors to be called like this: vector<int> u({3}), which is already currently legal.

like image 791
xdavidliu Avatar asked Feb 06 '18 05:02

xdavidliu


People also ask

What are the advantages of initializer list?

The most common benefit of doing this is improved performance. If the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object.

What is std :: Initializer_list?

An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .

What is mean by member initialisation list of constructor in C ++?

Member initializer lists allow us to initialize our members rather than assign values to them. This is the only way to initialize members that require values upon initialization, such as const or reference members, and it can be more performant than assigning values in the body of the constructor.

Why do we use initializer list in C++?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.


1 Answers

Has there been any discussion or plans by the C++ standard committee to fix this type of ambiguity / unpleasantness?

There have been many fixes to initialization since C++11. For instance, you initially couldn't copy construct aggregates using list-initialization (CWG 1467). This really minor fix broke some code in an undesirable way that lead to a new issue to refine that previous fix to undo it if there's an initializer_list constructor (CWG 2137). It's hard to touch anything in these clauses without lots of unexpected consequences and breaking code, even in small cases. I doubt there will be a push to make any kind of large change to initialization in the future. At this point, the amount of code breakage would be tremendous.

The best solution is just to be aware about the pitfalls of initialization and be careful about what you're doing. My rule of thumb is to only use {}s when I deliberately need the behavior that {} provides, and () otherwise.

Note that this isn't really any different from the more well-known pitfall of:

vector<int> a{10}; // vector of 1 element
vector<int> b(10); // vector of 10 elements

One example would be requiring initializer list constructors to be called like this: vector<int> u({3}), which is already currently legal.

You have the same problem you had before, for the same reasons:

vector<int> u({3});    // vector of one element: 3
vector<string> v({3}); // vector of three elements: "", "", and ""

Even if you were to require the former (which would be impossible), you couldn't make the latter ill-formed.

like image 100
Barry Avatar answered Sep 24 '22 03:09

Barry