sto*_*tic 0 c++ overloading ambiguous-call
我想创建一个"Tag"类,可以将其名称指定为点分隔名称,"this.is.my.name"或者作为字符串向量,如{"this","is","my","name"}.
当我尝试这样做时,编译器有时会告诉我我的调用是不明确的.我想知道(1)为什么这个含糊不清,以及(2)为什么它有时只是含糊不清.
这是我的示例代码,您也可以在Coliru上查看和编译
#include <string>
#include <vector>
#include <iostream>
class Tag
{
public:
explicit Tag(std::string name);
explicit Tag(std::vector<std::string> name);
};
Tag::Tag(std::string name)
{
//here 'name' will be a dotted collection of strings, like "a.b.c"
}
Tag::Tag(std::vector<std::string> name)
{
//here 'name' will be a vector of strings, like {"a","b","c"}
}
int main(int argc, char**argv)
{
Tag imaTag{{"dotted","string","again"}};
Tag imaTagToo{"dotted.string"};
//everything is fine without this line:
Tag imaTagAlso{{"dotted","string"}};
std::cout << "I made two tags" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
使用指示的行,我收到以下错误:
g++ -std=c++11 -O2 -Wall -pthread main.cpp && ./a.out
main.cpp: In function 'int main(int, char**)':
main.cpp:28:39: error: call of overloaded 'Tag(<brace-enclosed initializer list>)' is ambiguous
Tag imaTagAlso{{"dotted","string"}};
^
main.cpp:18:1: note: candidate: 'Tag::Tag(std::vector<std::__cxx11::basic_string<char> >)'
Tag::Tag(std::vector<std::string> name)
^~~
main.cpp:13:1: note: candidate: 'Tag::Tag(std::__cxx11::string)'
Tag::Tag(std::string name)
^~~
Run Code Online (Sandbox Code Playgroud)
Tag imaTagAlso{{"dotted","string"}}; 说构造一个Tag,调用它imaTagAlso并用它初始化它{"dotted","string"}.这个问题std::string可以由一对迭代器构造,因为字符串文字可以衰减为const char*s,它们有资格作为迭代器.因此,您可以使用"迭代器"调用字符串构造函数,也可以使用其std::initializer_list构造函数调用向量构造函数.要解决这个问题,您可以使用
Tag imaTagAlso{{{"dotted"},{"string"}}};
Run Code Online (Sandbox Code Playgroud)
它说构建Tag,把它imaTagAlso与初始化{{"dotted"},{"string"}},现在{"dotted"}和{"string"}成为的元素std::initializer_list为载体的构造.
你也可以(因为C++ 14)使用std::string的用户定义的字面符(""s)一样
Tag imaTagAlso{{"dotted"s,"string"s}};
Run Code Online (Sandbox Code Playgroud)
这将使braced-init-list std::string的每个元素和矢量构造函数都被选中.