【问题标题】:Derived class function parameter as base class reference is causing C2678派生类函数参数作为基类引用导致 C2678
【发布时间】:2015-02-19 12:40:05
【问题描述】:

我创建了“派生”类,它是“基”类的派生类。它正在使用 CRTP。基类包含一个一元和一个二元运算符。派生类正在实现这些虚拟运算符功能。

template <typename T> class Base
{
public:
    virtual bool operator==(T operand) = 0;
    virtual bool operator!() = 0;
};

class Derived : public Base<Derived>
{
public:
    virtual bool operator==(Derived operand){ return true; }
    virtual bool operator!(){ return false; }
};

模板函数 notf 和 equalf 用于测试 Derived 类的成员运算符。函数 notf 通过引用获取一个 Base,并调用它的 !操作员。函数 equalf 做类似的事情。

template <typename T> bool notf(Base<T>& x)
{
    return !x;
}

template <typename T> bool equalf(Base<T>& x, Base<T>& y)
{
    return x == y;
}

主函数调用那些模板函数。

int main()
{
    Derived x, y;
    cout << notf(x);
    cout << equalf(x, y);
    return 0;
}

并且在equalf函数上产生C2678错误。编译器说,error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Base&lt;Derived&gt;' (or there is no acceptable conversion)。但我不知道是什么问题,因为 notf 函数运行良好。代码编译除equalf函数外,运行良好。

当我制作equalf函数来显示参数的类型时,它显示“class Derived”和“class Derived”。如果是真的,那为什么错误信息是left-hand operand of type 'Base&lt;Derived&gt;'

【问题讨论】:

  • CRTP 通过非虚拟方法提供编译时多态性。虚拟方法提供运行时多态性。在您的案例中,CRTP 模式的目的是什么?或者虚拟方法的目的是什么?
  • @Cheersandhth.-Alf 我正在使用 CRTP 在基类中使用类型 T,因为基类中的 operator== 必须采用 T 类型参数。
  • 我认为 perhaps this 是你想要做的,但我仍然不清楚你为什么真的想要这样做。

标签: c++ templates inheritance crtp


【解决方案1】:

Base&lt;T&gt;::operator==(T operand) 不能接受 Base&lt;T&gt; 参数(因为没有定义转换)。

很难提出修复建议,因为代码指向许多可能的设计方向。

但是,无论如何,虚拟比较运算符或虚拟赋值的想法通常并不好,因为它将类型检查转移到运行时,因此您需要更多的测试和更复杂的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 2014-08-05
    • 2012-08-28
    • 2021-02-14
    • 2013-07-02
    • 1970-01-01
    • 2012-03-06
    相关资源
    最近更新 更多