我已经看到已经存在关于C ++中模棱两可的错误的问题,但这有点不同。
我们说我们的代码如下:
#include <iostream>
#define LDBG(msg) \
std::cout << "[" << __FUNCTION__ << " " << __LINE__ << "] " << msg << std::endl;
template<typename T>
struct AClass{
AClass(T a) {}
void Foo(const AClass<T> &other){
LDBG("")
}
void Foo(const T &key) const{
LDBG("")
}
};
int main(){
AClass<int> a1{1};
AClass<int> a2{2};
a1.Foo(1);
a1.Foo(a2);
LDBG("")
return 0;
}
这将产生编译错误,如:
error: call to member function 'Foo' is ambiguous
a1.Foo(1);
~~~^~~
note: candidate function
void Foo(const AClass<T> &other){
^
note: candidate function
void Foo(const T &key) const{
^
1 error generated.
如果错误将会消失:
void Foo(const T &key) const{
)或2.在void Foo(const AClass<T> &other)
的末尾添加一个const
或3.将构造函数更改为AClass() {}
(也是主函数中a1和a2的相对初始化)
或其他一些方式。
这三个或更多的整改如何破坏,原始问题是什么?
答案 0 :(得分:1)
此构造函数定义从T
到AClass<T>
的隐式转换:
AClass(T a) {}
鉴于a1.Foo(1)
:
void Foo(const AClass<T> &other)
是隐式对象参数的更好匹配,而other
上的匹配更差(因为它需要用户定义的转换)void Foo(const T& key) const
的添加,key
在const
上更好匹配(因为它是精确匹配)并且隐式对象参数更匹配。因为这两个函数都没有明显优于另一个函数(每个函数在一个参数上更好而在另一个参数上更差),所以调用是不明确的。
你的前两个修复使得两个函数同样好用w / r / t隐式对象参数,因此T
版本明确地获胜。第三个修复使AClass<T>
函数不再可行,因为隐式转换不再存在。