为何传入initializer_list调用vector重载函数会出现二义性?
为什么
fun({"a", "c"})会出现二义性? 核心原因:std::vector的构造函数重载与隐式转换的优先级冲突
当你调用fun({"a", "c"})时,编译器需要从两个fun重载中选择一个,但它发现两条可行的匹配路径,且优先级完全相同:
匹配
vector<string>的路径:std::vector<string>有一个接受std::initializer_list<string>的构造函数,而const char*可以隐式转换为string,所以初始化列表{"a", "c"}可以被转换为vector<string>。匹配
vector<long long>的路径:std::vector还有一个模板范围构造函数:template <class InputIterator> vector(InputIterator first, InputIterator last);编译器会把
{"a", "c"}里的const char*当成迭代器(指针符合迭代器的接口要求),尝试用这个范围构造函数创建vector<long long>:- 解引用
const char*得到char类型的值(比如'a'对应ASCII码97) char可以隐式转换为long long
这条路径同样合法,且转换序列的优先级和第一条路径一致。
- 解引用
因为两条路径都合法且优先级相同,编译器无法判断你想要调用哪个重载,所以报二义性错误。
为什么添加initializer_list<const char*>的重载能解决问题?
当你新增:
void fun(std::initializer_list<const char*> s) {}
这个重载直接匹配初始化列表{"a", "c"}的原始类型——不需要任何隐式转换(既不用转string,也不用转long long)。根据C++重载决议规则,完全匹配的优先级高于需要隐式转换的匹配,所以编译器会直接选择这个重载,二义性随之消失。
内容的提问来源于stack exchange,提问作者kilasuelika
相关产品推荐
相关产品推荐

