来自 CRTP 基础的 Operator++ 对编译器不可见

Operator++ from CRTP base is not visible for compiler

以下面一段代码为例:

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
}

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

error: no 'operator++(int)' declared for postfix '++' [-fpermissive]

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

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

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

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

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