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.