首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >重载的<花括号内的初始值设定项list>调用不明确,该如何处理?

重载的<花括号内的初始值设定项list>调用不明确,该如何处理?
EN

Stack Overflow用户
提问于 2013-01-30 00:25:59
回答 1查看 5.9K关注 0票数 21

我真的不明白这一点,我以为编译器会先执行大括号中的内容,然后将结果传递给最合适的函数。这里它看起来像是给了函数一个初始化列表来处理它…

代码语言:javascript
复制
#include <string>
#include <vector>
using namespace std;

void func(vector<string> v) { }

void func(vector<wstring> v) { }

int main() {
  func({"apple", "banana"});
}

错误:

代码语言:javascript
复制
<stdin>: In function 'int main()':
<stdin>:11:27: error: call of overloaded 'func(<brace-enclosed initializer list>)' is ambiguous
<stdin>:11:27: note: candidates are:
<stdin>:6:6: note: void func(std::vector<std::basic_string<char> >)
<stdin>:8:6: note: void func(std::vector<std::basic_string<wchar_t> >)

为什么没有调用我的 func(vector<string> v) 重载,我可以这样做吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-30 01:34:09

这是一个微妙的问题。

std::vector有一个接受两个范围迭代器的构造函数。它是一个模板构造函数(在C++11标准的23.6.6.2中定义):

代码语言:javascript
复制
template<typename InputIterator>
vector(InputIterator first, InputIterator last, 
const allocator_type& a = allocator_type());

现在,std::vector<wstring>接受initializer_list的构造器与函数调用中的隐式转换不匹配(const char*string是不同的类型);但是上面的构造器(当然包含在std::vector<string>std::vector<wstring>中)可能是一个完美的匹配项,因为InputIterator可以推断为const char*。除非使用一些SFINAE技术来检查推导出的模板参数是否确实满足向量底层类型的InputIterator概念(这不是我们的情况),否则这个构造函数是可行的。

但话又说回来,std::vector<string>std::vector<wstring>都有一个可行的构造函数,可以实现从带括号的初始化器列表的转换:因此,有歧义。

所以问题在于,尽管"apple""banana"不是真正的迭代器(*),但它们最终被视为迭代器。将一个参数"joe"添加到函数调用可以通过消除调用的歧义来解决这个问题,因为这会迫使编译器排除基于范围的构造函数,并选择仅可行转换(initializer_list<wstring>不可行,因为const char*不能转换为wstring)。

*实际上,它们是指向const char的指针,因此它们甚至可以被视为字符的常量迭代器,但绝对不是我们的模板构造函数愿意考虑的字符串的迭代器。

票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14587436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档