CRTP base的Operator ++对于编译器不可见

时间:2019-03-17 21:42:31

标签: c++ operator-overloading crtp

以下面的代码为例:

template<class Derived>
struct base {
    Derived operator++(int){
        auto tmp = static_cast<Derived &>(*this);
        ++static_cast<Derived &>(*this);
        return tmp;
    }
};

struct der : public base<der> {
    der &operator++(){
        return *this;
    }
};

int main(){
    der d;
    d++;/// <<< compilation error here
}

我从编译器中收到以下错误:

  

错误:后缀'++'[-fpermissive]没有声明'operator ++(int)'

为什么后缀运算符对编译器不可见?它包含某种错误还是我的C ++功能未知?可以修复此代码,以便后缀operator++可以按预期工作吗?

2 个答案:

答案 0 :(得分:3)

您的两个函数具有相同的名称,operator++。它的拼写与使用标识符命名的函数的拼写不同。类成员查找的规则是默认情况下,如果在派生类中找到具有该名称的成员,则不检查基类。派生成员“隐藏”基础成员。

避免使用不同的签名隐藏基类函数并允许重载解析选择最佳函数的通常方法是使用using声明:

struct der : public base<der> {
    der &operator++(){
        return *this;
    }
    using base<der>::operator++;
};

答案 1 :(得分:1)

将名称operator++替换为名称f(即使用普通成员函数尝试相同的操作)。您也会遇到同样的问题。编译器会在der中找到命名函数,因此不会在base<dir>中查找。重载仅在相同作用域中定义的函数之间发生。