CRTP基础的操作员 对于编译器而言不可见

Operator++ from CRTP base is not visible for compiler

本文关键字:编译器 操作员 CRTP      更新时间:2023-10-16

以以下代码为例:

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
}

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

错误:否'operator (int)'为postfix' '[-fpermissive]

为什么我的后缀操作员在编译器中不可见?它是否包含某种错误,还是我C 功能不知道?可以修复此代码以使后缀operator++按预期工作吗?

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

避免使用不同签名隐藏基类功能并允许超载分辨率选择最佳功能的通常方法是使用使用:

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

用名称 f替换名称operator++(即使用普通成员函数尝试相同的东西)。您会遇到同样的问题。编译器在der中找到命名函数,因此它不会在base<dir>中查看。超载仅发生在同一范围中定义的函数之间。