Why does the following code give different output?
std::vector<int> v{12};
std::cout << v.size() << std::endl;
std::vector<int> v(12);
std::cout << v.size() << std::endl;
What if I list-initialize an object which has a ctor accepting an initializer_list as parameter?
And how can I call std::vector::vector(size_t)
with list-initialization?
CodePudding user response:
List-initialization prefers constructors with a std::initializer_list
argument. From cppreference:
The effects of list-initialization of an object of type T are:
[...cases that do not apply here ...]
- Otherwise, the constructors of T are considered, in two phases:
All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list
If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).
While direct initialization does not prefer the initializer_list constructor. It calls the constructor that takes the size as argument.
And from https://en.cppreference.com/w/cpp/container/vector/vector:
Note that the presence of list-initializing constructor (10) means list initialization and direct initialization do different things:
std::vector<int> b{3}; // creates a 1-element vector holding {3} std::vector<int> a(3); // creates a 3-element vector holding {0, 0, 0} std::vector<int> d{1, 2}; // creates a 2-element vector holding {1, 2} std::vector<int> c(1, 2); // creates a 1-element vector holding {2}
And how can I call std::vector::vector(size_t) with list-initialization?
As explained above, the presence of the std::initializer_list
constructor prevents you from calling the other constructor via list-initialization.