有没有办法区分来​​自两个模板化基类的这些函数调用?

时间:2012-06-22 16:38:32

标签: c++ templates inheritance virtual-functions

我有以下情况: -

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();

我希望能够区分这两个函数调用。换句话说,用不同的功能体覆盖两个基本功能。

3 个答案:

答案 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();
}