仅覆盖模板中某些类型的函数

时间:2012-06-02 15:11:21

标签: c++ templates override

我有一个带虚函数的基类:

class Base
{
public:
  virtual void Function();
};

void Base::Function()
{
  cout << "default version" << endl;
}

和派生的模板类:

template <class T> class Derived : public Base
{
public:
  virtual void Function();
};

有没有办法让Function()从所有类型的基类中删除,除了一些选择的类型?所以我想要的是能够为Function()int定义覆盖long

void Derived<int>::Function()
{
  cout << "overriden version 1" << endl;
}

void Derived<long>::Function()
{
  cout << "overriden version 2" << endl;
}

并且对于所有其他类型都有Function()的默认版本,没有明确定义Function(),所以输出

int main ()
{
  Derived<int> derivedInt;
  derivedInt.Function();

  Derived<long> derivedLong;
  derivedLong.Function();

  Derived<double> derivedDouble;
  derivedDouble.Function();
}

将是

overriden version 1
overriden version 2
default version

有可能吗?

3 个答案:

答案 0 :(得分:4)

类模板的成员函数实际上是函数模板,因此您可以对它们进行特化:

template <typename T> class Foo
{
    void Function();
};

template <typename T> void Foo::Function() { /* ... */ }

template <> void Foo<int>::Function() { /* ... */ }

答案 1 :(得分:3)

是的,通过专门化Derived

  • 在没有它的情况下编写通用版本(它将从Base继承它)
  • 专门设置Derived以覆盖

简单的方案,但它有效。

答案 2 :(得分:1)

第一个解决方案(使用typeid运算符)

#include <iostream>
#include <typeinfo>

using namespace std;

class Base
{
public:
    virtual void Function();
};

void Base::Function()
{
    cout << "default version\n";
}

template<typename T>
class Derived : Base
{
public:
    virtual void Function();
};

template<typename T>
void Derived<T>::Function()
{
    if(typeid(T) == typeid(int)) // check if T is an int
    {
        cout << "overriden version 1\n";
    }
    else if(typeid(T) == typeid(long)) // check if T is a long int
    {
        cout << "overriden version 2\n";
    }
    else // if T is neither an int nor a long
    {
        Base::Function(); // call default version
    }
}

int main()
{
    Derived<int> di;
    Derived<long> dl;
    Derived<float> df;

    di.Function();
    dl.Function();
    df.Function();

    return 0;
}

我使用typeid运算符检查T是int还是long int,如果是,我打印“覆盖版本[编号]”。如果不是,我打电话给Base::Function(),这将打印“默认版本”

注意:要使用typeid运算符,您需要包含头文件typeinfo

第二个解决方案(使用模板专精)

// class declarations as before

template<typename T>
void Derived<T>::Function()
{
    Base::Function(); // call default version
}

template<>
void Derived<int>::Function()
{
    cout << "overriden version 1\n";
}

template<>
void Derived<long>::Function()
{
    cout << "overriden version 2\n";
}

int main()
{
    Derived<int> di;
    Derived<long> dl;
    Derived<float> df;

    di.Function();
    dl.Function();
    df.Function();

    return 0;
}

在这里,我用模板特化解决了你的问题。如果T是intlong int,我会调用专用版本。否则,我称之为通用版本,相当于Base::Function()