你如何在子类中重载模板化函数(专用)?

时间:2011-08-11 21:43:48

标签: c++ templates

我有一个带有模板化函数的基类,它具有一般的模板类型,以及专用版本。

#ifndef BASE_CLASS
#define BASE_CLASS

#include <iostream>

using namespace std;

struct Type1
{
};

struct Type2
{
};

class baseClass
{
    public:
    template<class Type>
    void doStuff(Type & t)
        {
        templateFunction(t);  
        }

    template<class Type>
    void templateFunction(Type & t);
};

template<class Type>
void baseClass::templateFunction(Type & t)
{
    cout << "This is the generic function!" << endl;
}

template<>
void baseClass::templateFunction(Type1 & t)
{
    cout << "This is the specialized function: - Type1" << endl;
}
#endif

我还有一个继承自“baseClass”的子类。但是,子类需要针对该特化的不同功能。

#ifndef CHILD_CLASS
#define CHILD_CLASS

#include "BaseClass.h"

class ChildClass : public baseClass
{
    public:

};

template<>
void ChildClass::templateFunction(Type1 & t)
{
    cout << "We overloaded the specialized template function for type 1!" << endl;
}

#endif

上面没有编译:

ChildClass.h:13:错误:没有在âChildClass中声明的成员函数âtemplateFunctionâ ChildClass.h:13:错误:函数声明无效

如果我将“重载”功能更改为:

template<>
void baseClass::templateFunction(Type1 & t)
{
    cout << "We overloaded the specialized template function for type 1!" << endl;
}

我得到: ChildClass.h:13:错误:重新定义âvoidbaseClass:: templateFunction(Type&amp;)[with Type = Type1]â BaseClass.h:36:错误:âvoidbaseClass:: templateFunction(Type&amp;)[with Type = Type1]â在此声明

如何正确地重载子类中的专用模板函数?

供参考,主要是:

#include "BaseClass.h"
#include "ChildClass.h"

int main()
{
    Type1 first;
    Type2 second;

    baseClass theBaseClass;
    ChildClass theChildClass;


    theBaseClass.doStuff(first);
    theBaseClass.doStuff(second);

    theChildClass.doStuff(first);
    theChildClass.doStuff(second);

    return 0;
}

根据以下建议:Kerrek SB,我已将ChildClass更改为:

#ifndef CHILD_CLASS
#define CHILD_CLASS

#include "BaseClass.h"
class ChildClass : public baseClass
{
    public:
    template<class Type>
    void templateFunction(Type & t);
};

template<>
void ChildClass::templateFunction(Type1 & t)
{
    cout << "We overloaded the specialized template function for type 1!" << endl;
}

#endif

输出:

This is the specialized function: - Type1
This is the generic function!
This is the specialized function: - Type1
This is the generic function!

我希望:

This is the specialized function: - Type1
This is the generic function!
We overloaded the specialized template function for type 1!
This is the generic function!

所以这仍然不起作用。

2 个答案:

答案 0 :(得分:5)

它仍然无法以您想要的方式工作的原因是该功能在父类中不是虚拟的。但是,无法使用虚拟模板功能。

我看到两个主要选项:

  • 正如rhalbersma建议的那样,使类本身模板,然后在子类中覆盖所需的方法(现在不是模板)。
  • 对于专门的方法,只需编写一个具有不同名称的新方法,即可满足您的需要。

但我相信有人会想出更好的主意...... =)

答案 1 :(得分:2)

您可以使用如下虚拟函数创建模板类:

template<typename T>
class B
{
    virtual void f() { std::cout << "base template implementation \n"; }
};

template<>
class B<Type1>
{
    virtual void f() { std::cout << "base specialized implementation \n"; }
};

template<typename T>
class D: public B<T>
{
    virtual void f() { std::cout << "derived template implementation \n"; }
};

template<>
class D<Type1>: public B<Type1>
{
    virtual void f() { std::cout << "derived specialized implementation \n"; }
};

B<Type1> b1;
B<Type2> b2;
D<Type1> d1;
D<Type2> d2;

b1.f();
b2.f();
d1.f();
d2.f();

现在有两个独立的自定义维度:模板T或动态类型(B对D)。对于每个模板实例化,可以重新定义虚函数。

更常见的是让B成为具有纯虚函数的常规类(即接口),让D成为从B派生的模板类。这使您可以为每个模板以不同的方式重新定义B的虚函数D的实例化(具有合适的默认值)。