我看到已经有关于 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.
如果出现以下情况,错误将消失:
- 删除第 14 行的常量 (
void Foo(const T &key) const{
)
或者2.在void Foo(const AClass<T> &other)
的末尾添加一个const也是
或 3. 将构造函数更改为 AClass() {}
(也是main函数中a1和a2的相对初始化)
或者其他一些方式。
这3个以上整改是怎么回事,原来的问题是什么?
最佳答案
此构造函数定义了从 T
的隐式转换至 AClass<T>
:
AClass(T a) {}
给定a1.Foo(1)
:
-
void Foo(const AClass<T> &other)
是对隐式对象参数的更好匹配,对other
的匹配更差(因为它需要用户定义的转换) -
void Foo(const T& key) const
是key
上的更好匹配(因为它是完全匹配)并且由于添加了const
而与隐式对象参数的匹配更差.
因为两个函数都没有明显优于另一个(每个函数在一个参数上更好而在另一个参数上更差),所以调用是不明确的。
您的前两个修复使这两个函数在不带隐式对象参数的情况下同样好用,因此 T
版本明确获胜。您的第三次修复使得 AClass<T>
函数不再可行,因为隐式转换不再存在。
关于C++ 成员函数不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40814691/