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

koo*_*ana 59 c++ initializer-list ambiguous overload-resolution

为什么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;
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 59

这里发生的是在两个元素的初始化列表中,两个字符串文字都可以隐式转换为const char*它们的类型const char[N].现在std::vector有一个构造函数,它接受指针符合条件的两个迭代器.因为它的initializer_list构造函数std::vector<std::string>与迭代器范围构造函数冲突std::vector<int>.

如果我们改变代码而不是

doSomething({"hello"s, "stack"s});
Run Code Online (Sandbox Code Playgroud)

然后,初始化列表的元素现在std::string是s,因此没有歧义.

  • 或者`doSomething(std :: vector <std :: string>({"hello","stack"}));`,但你的解决方案更具可读性.在任何情况下,如果这是真实的代码,我可能还会添加一个小注释来解释看似无用的显式. (6认同)

Que*_*tin 23

无论是单参数和三参数列表只能匹配std::vector<std::string>std::initializer_list构造函数.但是,双参数列表与以下构造函数之一匹配std::vector<int>:

template <class InputIt>
vector(InputIt first, InputIt last, Allocator const &alloc = Allocator());
Run Code Online (Sandbox Code Playgroud)

实际上,a char const *可以递增,并且取消引用以获得char可隐式转换为a的int.


Fra*_*eux 17

"hello"并且"stack"两者都const char *满足InputIterator概念.这允许他们匹配std::vector的构造函数#4.

如果传递std::string对象,则会解决歧义.