为什么初始化程序列表中的元素数量会导致模糊的调用错误?

为什么前两个调用做编译器的某些doSomething ,但在列表中使用两个元素会导致模糊的调用?

 #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; } 

这里发生的事情是,在两个元素初始值设定项列表中,两个string文字可以隐式转换为const char*因为它们的types是const char[N] 。 现在std::vector有一个构造函数,它需要两个指针符合的迭代器。 因为std::vector<std::string>initializer_list构造函数与std::vector<int>的迭代器范围构造函数冲突。

如果我们改变代码而不是

 doSomething({"hello"s, "stack"s}); 

那么初始化器列表的元素现在是std::string s,所以没有歧义。

单参数和三参数列表只能匹配std::vector<std::string>std::initializer_list构造函数。 但是,两个参数列表匹配来自std::vector<int>的构造函数之一:

 template <class InputIt> vector(InputIt first, InputIt last, Allocator const &alloc = Allocator()); 

事实上, char const *可以增加,并取消引用可以隐式转换为intchar

"hello""stack"都衰减到满足InputIterator概念的const char * 。 这允许他们匹配std::vector的构造函数#4 。

如果您传递std::string对象,则解决了歧义。