【发布时间】:2019-08-29 19:37:02
【问题描述】:
下面代码中函数调用出现歧义的原因是什么?
我知道这里有两个可行的函数,正如编译器在 ERROR 消息中所说的那样(如下所示)
1) candidate: operator==(Base*, Base*)
-> 第一个参数需要用户定义从SmartPtr 到Base* 的转换
-> 需要 Derived* 到 Base* 隐式 (?) 转换
2)candidate: bool operator==(const SmartPtr&, const Base*)
-> 需要为第一个参数添加顶级 const(精确匹配)
-> 需要 Derived* 到 Base* 隐式 (?) 转换
从上面很明显,SmartPtr 内部定义的operator== 是更好的匹配(考虑到第一个参数和第二个参数相同)
代码:
#include <iostream>
using namespace std;
template<class T> class SmartPtr
{
public:
operator T*() { return pointee__;}
inline friend bool operator==(const SmartPtr& lhs, const T* rhs){
return lhs.pointee__ == rhs;
}
private:
T* pointee__;
};
struct Base{};
class Derived:public Base{};
int main()
{
SmartPtr<Base> sp;
Derived * dp;
cout<<"Hello World"<< (sp==dp);
return 0;
}
错误:
main.cpp: In function ‘int main()’:
main.cpp:38:30: error: ambiguous overload for ‘operator==’ (operand types are ‘SmartPtr’ and ‘Derived*’)
cout<<"Hello World"<< (sp==dp);
~~^~~~
main.cpp:38:30: note: candidate: operator==(Base*, Base*)
main.cpp:19:24: note: candidate: bool operator==(const SmartPtr&, const Base*)
inline friend bool operator==(const SmartPtr& lhs, const T* rhs){
^~~~~~~~
谢谢!
【问题讨论】:
-
我建议阅读this。
-
这并没有解决问题,但包含两个连续下划线 (
pointer__) 的名称和以下划线后跟大写字母的名称保留供实现使用。不要在你的代码中使用它们。