Reputation: 719
Why are the first two calls to doSomething
OK by the compiler, but using two elements in the list causes an ambiguous call?
#include <vector>
#include <string>
void doSomething(const std::vector<std::string>& data) {}
void doSomething(const std::vector<int>& data) {}
int main(int argc, char *argv[])
{
doSomething({"hello"}); // OK
doSomething({"hello", "stack", "overflow"}); // OK
doSomething({"hello", "stack"}); // C2668 'doSomething': ambiguous call
return 0;
}
Upvotes: 60
Views: 3147
Reputation: 1
may be you can overload the doSomething() with initializer_list parameter, like this:
void doSomething(initializer_list<string> l) {
doSomething(vector<string>(l));
}
then, doSomething({"hello", "stack"});
will call the function you desired.
Upvotes: 0
Reputation: 29023
"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.
Upvotes: 17
Reputation: 180490
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.
Upvotes: 62
Reputation: 63124
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
.
Upvotes: 23