我尝试将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
公开继承),所以我认为它应该是可访问的。
我不确定我在这里缺少什么,任何提示都将深受赞赏。
答案 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
}
};