函数未解析为基类重载

Function not resolving to base class overload

本文关键字:基类 重载 函数      更新时间:2023-10-16

我尝试在这个(简化的)示例中使用 CRTP:

基类:

template <class Derived>
class Base
{
public: 
    int method(int in, int& out2)
    {
        return derived().method(in, out2);
    }
    int method(int in)
    {
        int dummy;
        return this->predict(in, dummy);
    }
protected:
    Base() {}
private:
    Derived& derived()
    {
        return *static_cast<Derived*>(this);
    }
};

派生类:

class Derived : public Base<Derived>
{
public: 
    int method(int in, int& out2)
    {
        // Logic here
    }
};

问题是,当我尝试将method(int in)Derived类的实例一起使用时,例如:

Derived d;
int res = d.method(5);

编译器(在这种情况下为 icc,但也尝试使用 msvc)给了我以下错误:

错误 #165:函数调用中的参数太少

编译器似乎没有意识到存在一个重载,它只从Base<Derived>类中获取一个参数(Derived从中公开继承,所以我认为它应该是可访问的)。

不确定我在这里错过了什么,任何提示都将不胜感激。

Derived::method的存在意味着编译器在尝试绑定调用时不会考虑Base::method的重载。若要解决此问题,请将using Base::method;添加到派生类:

class Derived : public Base<Derived>
{
public:
    using Base::method; 
    int method(int in, int& out2)
    {
        // Logic here
    }
};

当一个非虚函数被定义为与Base::method同名时,它会掩盖Derived类中的Base::method,这也被称为名称隐藏

为了防止这种情况,您必须使用 using 运算符显式提及带有类的方法名称,即您的Derived类代码应修改为:

class Derived : public Base<Derived>
{
public: 
    using Base::method; //makes the 'method' declaration of Base class 
                        //visible here as well.
    int method(int in, int& out2)
    {
        // Logic here
    }
};