【问题标题】:c++ method call (lvalue) binding to function(rvalue) in derived class instead of function(lvalue) in base classc ++方法调用(左值)绑定到派生类中的函数(右值)而不是基类中的函数(左值)
【发布时间】:2017-08-04 11:44:14
【问题描述】:

我是 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\" %d\n", m1.getName(), m2.getName(), m2.compare(m1));

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

无法将“Tests::Monkey”左值绑定到“const Tests::Monkey&&” 初始化 'virtual int Tests::Monkey::compare(const Tests::Monkey&&)' 的参数 1 构建失败

为什么方法调用没有绑定到基类中的 compare 方法?

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

【问题讨论】:

  • 我真的不明白你为什么到处使用右值引用。 compare 函数的普通 const-reference 可以正常工作。并将右值引用传递给const char*?这真的没有多大意义。最后,常量右值引用通常也没有任何意义。
  • 我是 C++ 新手。我认为引用防止复制,这是函数调用的默认行为,所以我认为养成使用它们的习惯并习惯它们可能是一个好习惯。我以前见过 const 引用。虽然它对性能的影响可能可以忽略不计。
  • @JoePaul Reference 也介绍了overhead。 const lvalue 参考在你的情况下会很完美。右值引用主要用于完善转发和移动语义。

标签: c++ binding virtual lvalue rvalue


【解决方案1】:

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

根据unqualified name lookup的规则,对于m2.compare(m1)m2的类型为Monkey,名称compare会在派生类Monkey的范围内先找到,再名称查找停止。基类中的 compares 根本不会被考虑用于以下重载解决方案。

(强调我的)

对于非限定名称,即未出现在范围解析运算符 :: 右侧的名称,名称查找会检查如下所述的范围,直到找到至少一个任何类型的声明,此时查找停止并且不再检查范围

您可以通过using将基类的名称引入派生类的作用域:

class Monkey : Comparable<Monkey>
{
      ...

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多