函数未解析为基类重载

时间:2015-01-28 01:14:53

标签: c++ crtp

我尝试将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公开继承),所以我认为它应该是可访问的。

我不确定我在这里缺少什么,任何提示都将深受赞赏。

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

如果使用与Base::method相同的名称定义非虚拟函数,则遮盖 Base::method类中的Derived,这也是称为名称隐藏

为防止出现这种情况,您必须使用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
    }
};