Why does the number of elements in a initializer list cause an ambiguous call error?
What is happening here is that in the two element initializer list both of the string literals can be implicitly converted to const char*
since their type is const char[N]
. Now std::vector
has a constructor that takes two iterators which the pointers qualify for. Because of that the initializer_list
constructor of the std::vector<std::string>
is conflicting with the iterator range constructor of std::vector<int>
.
If we change the code to instead be
doSomething({"hello"s, "stack"s});
Then the elements of the initializer list are now std::string
s so there is no ambiguity.
Both the one-argument and three-argument lists can only match std::vector<std::string>
's std::initializer_list
constructor. However, the two-argument list matches one of the constructors from std::vector<int>
:
template <class InputIt>
vector(InputIt first, InputIt last, Allocator const &alloc = Allocator());
Indeed, a char const *
can be incremented, and dereferenced to get a char
that is implicitly convertible to an int
.
"hello"
and "stack"
both decay to const char *
which satisfies the InputIterator concept. This allow's them to match std::vector
's constructor #4.
If you pass std::string
objects the ambiguity is resolved.