派生类函数参数作为基类引用导致C2678

时间:2015-02-19 12:40:06

标签: c++ templates inheritance crtp

我制作了' Derived'正在派生的基地'类。它正在使用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<Derived>' (or there is no acceptable conversion)。但我不知道什么是问题,因为notf功能运行良好。当代码编译时除了equalf函数,它运行良好。

当我使用equalf函数来显示参数的类型时,它会显示&#34; class Derived&#34;和&#34;类Derived&#34;。如果这是真的,那么为什么错误消息会显示left-hand operand of type 'Base<Derived>'

1 个答案:

答案 0 :(得分:2)

Base<T>::operator==(T operand)无法接受Base<T>参数(因为没有定义转换)。

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

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