为什么初始化程序列表中的元素数量会导致模糊的调用错误?
为什么前两个调用做编译器的某些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 *
可以增加,并取消引用可以隐式转换为int
的char
。
"hello"
和"stack"
都衰减到满足InputIterator概念的const char *
。 这允许他们匹配std::vector
的构造函数#4 。
如果您传递std::string
对象,则解决了歧义。