我有以下情况: -
template <typename T>
class Base {
public:
virtual void someFunc() {}
};
class Derived : public Base<int>,
public Base<float> {
public:
virtual void someFunc() {
// do something different if Base<int> than if Base<float>
}
};
Derived *d = new D();
Base<int>* b1 = (Base<int>*) d;
Base<float>* b2 = (Base<float>*) d;
b1->someFunc();
b2->someFunc();
我希望能够区分这两个函数调用。换句话说,用不同的功能体覆盖两个基本功能。
答案 0 :(得分:3)
您可以使用填充程序(这适用于基类之间的任何名称冲突实例,无论是否与模板相关):
template <typename T>
class Base
{
public:
virtual void someFunc() {}
};
class IntShim : public Base<int>
{
protected:
virtual void someFuncViaInt() = 0;
public:
virtual void someFunc() { return someFuncViaInt(); }
};
class FloatShim : public Base<float>
{
protected:
virtual void someFuncViaFloat() = 0;
public:
virtual void someFunc() { return someFuncViaFloat(); }
};
class Derived : public IntShim, public FloatShim
{
protected:
virtual void someFuncViaInt()
{
// do something for Base<int>
}
virtual void someFuncViaFloat()
{
// do something for Base<float>
}
};
Derived *d = new D();
Base<int>* b1 = (Base<int>*) d;
Base<float>* b2 = (Base<float>*) d;
b1->someFunc();
b2->someFunc();
答案 1 :(得分:0)
您可以实现此方法的一种方法是在someFunc
上向Base
添加虚拟参数:
virtual void someFunc(T *dummy = nullptr);
在派生类中,您的覆盖是
virtual void someFunc(int *);
virtual void someFunc(float *);
而不是T *
你可以创建一个空类型
template<typename T> struct dispatch {};
...
virtual void someFunc(dispatch<T> = dispatch<T>());
...
virtual void someFunc(dispatch<int>);
virtual void someFunc(dispatch<float>);
这消除了传递nullptr的(最小)开销,并有助于阐明参数的用途。
答案 2 :(得分:0)
您不需要为此使用虚函数和派生类。您可以将Base类中的函数专门用于已知类型。
你可以做s.th.像这样:
template <typename T>
class Base {
public:
void someFunc()
{
// default implementation for any type
}
};
// specialization for int
template<> void Base<int>::someFunc()
{
}
// specialization for float
template<> void Base<float>::someFunc()
{
}
int main(int argc, char** argv)
{
Base<int>* b1 = new Base<int>();
Base<float>* b2 = new Base<float>();
b1->someFunc();
b2->someFunc();
}