C++ 方法调用 (lvalue) 绑定到派生类中的函数 (rvalue),而不是基类中的函数 (lvalue)

c++ method call (lvalue) binding to function(rvalue) in derived class instead of function(lvalue) in base class

本文关键字:函数 lvalue rvalue 基类 调用 方法 绑定 派生 C++      更新时间:2023-10-16

我是C++新手,并尝试编写如下接口:

template <class T>
class Comparable
{
protected:
Comparable(){};
public:
virtual int compare(const T&&)=0;
int compare(const T& o)
{
return this->compare(std::move(o));
}
};

我这样做是为了尝试让比较方法同时使用两个 l/r 值。 我从 Comparable 派生了以下类:

class Monkey : Comparable<Monkey>
{
private:
char name[512];
public:
Monkey(const char*&& name)
{
strcpy(this->name, name);
}
const char *getName() { return name; }
int compare(const Monkey&& m)
{
return strcmp(name, m.name);
}
};

使用 main() 方法如下:

Monkey m1(argv[1]), m2(argv[2]);
printf(""%s" "%s" %dn", m1.getName(), m2.getName(), m2.compare(m1));

但是我收到一个编译错误:

无法将"测试::猴子">

的左值绑定到"常量测试::猴子&&" 初始化"虚拟整数测试::猴子::比较(常量测试::猴子&&)"的参数 1 构建失败

为什么方法调用未绑定到基类中的比较方法?

当我在基类中将它们创建为虚拟并在派生类中将它们都写入时,绑定工作正常,但它不起作用,如果我尝试按照此处编写的方式编译它,则会出现编译错误。

这是名称隐藏;派生类中的名称隐藏基类中的名称。简而言之,您不能通过不同的作用域重载函数。

根据非限定名查找的规则,对于m2.compare(m1)m2的类型为Monkey,名称compare将首先在派生类的范围内找到Monkey,然后停止名称查找。基类中的compare根本不会考虑用于以下重载解析。

(强调我的)

对于非限定名称(即未显示在作用域解析运算符 :: 右侧的名称),名称查找将按如下所述检查作用域,直到找到至少一个任何类型的声明,此时查找将停止,不再检查作用域

您可以通过以下using将基类的名称引入派生类的范围:

class Monkey : Comparable<Monkey>
{
...
using Comparable<Monkey>::compare;
int compare(const Monkey&& m)
{
return strcmp(name, m.name);
}
};