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::strings 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.