调用重载<大括号括起来的初始值设定项列表>是模棱两可的,如何处理?
call of overloaded <brace-enclosed initializer list> is ambiguous, how to deal with that?
我真的不明白这一点,我认为编译器首先执行大括号中的内容,然后将结果提供给最合适的函数。在这里,它看起来像是给函数一个初始值设定项列表来处理它......
#include <string>
#include <vector>
using namespace std;
void func(vector<string> v) { }
void func(vector<wstring> v) { }
int main() {
func({"apple", "banana"});
}
错误:
<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)
过载不被调用,我可以这样做吗?
这个很微妙。
std::vector
有一个构造函数,采用两个范围迭代器。它是一个模板构造函数(在 C++11 标准的 23.6.6.2 中定义):
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
的指针,因此它们甚至可以被视为字符的常量迭代器,但绝对不是字符串,因为我们的模板构造函数愿意考虑。
- EASTL矢量<向量<int>>连续的
- "Inverse SFINAE"避免模棱两可的过载
- 操作员C++的模棱两可的过载
- 模棱两可的重载模板
- 调用重载的"<大括号括起来的初始值设定项列表>"对于对来说就足够了是模棱两可的
- 模棱两可的 != reverse_iterator运算符
- SFINAE不能防止模棱两可的操作员过载吗?
- VSCode 说 std::chrono 是模棱两可的,如果运算符<<重载
- 为什么对模板的调用不模棱两可?
- 修复重载运算符的使用'+'模棱两可?
- 为什么同时覆盖全局新运算符和特定于类的运算符不是模棱两可的行为?
- Antlr4 C++访问模棱两可的分支
- 模棱两可的调用 - 模板化函数
- 在SESHAT中,对"元组"的引用是模棱两可的
- C++17 年与 Clang 的模棱两可的部分专业化
- gcc 中的模棱两可的运算符
- 将 NULL 转换为长不是模棱两可吗?
- C++ lambda 模棱两可的调用
- 带有模板的循环缓冲区在Keil MDK5上是模棱两可的错误?
- C++11 中对超载'ref(Select::Expressions::Code&)'的调用模棱两可