函数调用歧义(用户定义的转换和 Derived2Base 指针转换)

Function call ambiguity (user-defined conversion and Derived2Base pointer conversion)

本文关键字:转换 Derived2Base 指针 歧义 用户 定义 函数调用      更新时间:2023-10-16

下面代码中函数调用歧义的原因是什么?

我知道这里有两个可行的函数,正如编译器在ERROR消息中所说的那样(如下所示在末尾(

1(candidate: operator==(Base*, Base*)

-> 需要用户定义的第一个参数从SmartPtrBase*的转换

-> 需要Derived*才能Base*隐式 (( 转换

2(candidate: bool operator==(const SmartPtr&, const Base*)

-> 需要为第一个参数添加顶级常量(完全匹配(

-> 需要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){
^~~~~~~~

谢谢!

从上面很明显,在 SmartPtr 中定义的运算符 == 是更好的匹配(考虑到第一个参数(

不完全是:第一个转换为SmartPtr &转换为SmartPtr const &

第二个需要两个转换:

1( 从Derived *Base *

2(从Base *Base const *

如果定义

Derived * dp;

指向const的指针

Derived const * dp;

歧义消失,代码编译。

如果定义spconst,则相同

SmartPtr<Base> const sp{};

如果修改SmartPtr内部的operator==()以接受Base *(而不是Base const *(作为第二个参数,也会消失。