2011-08-11 129 views
3

我有一個基類,模板函數具有一般的模板類型,以及專門的版本。你如何重載兒童班的模板化功能(專業)?

#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:錯誤:沒有成員函數âtemplateFunctionâ宣佈âChildClassâ ChildClass.h:13:錯誤:無效的函數聲明

如果我改變 「重載」 功能:

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

我得到: ChildClass.h:13:錯誤:避免巴的重新定義seClass :: templateFunction(類型&)與類型=類型1]答 BaseClass.h:36:錯誤:避免基類:: templateFunction(類型&)與類型=類型1]以前在這裏宣佈

怎麼辦我在子類中正確地重載了​​專門的模板函數?

作爲參考,主:

#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! 

所以這仍然不起作用。

+1

模板化的功能不能是虛擬的,你確定你的意思是重新定義的成員函數在派生類中,而*隱藏*原始功能?你不能通過指向基地的重定義函數!如果您確定,那麼您還應該將非專用聲明添加到派生類中。 –

+0

我不需要訪問baseClass的原始專用功能,沒有。至少對於任何給定的ChildClass實例。 – Alex

+1

那麼,在這種情況下,我相信你應該能夠做到這一點,如果你將該函數的主模板聲明添加到派生類,然後再進行專門化。 –

回答

5

它仍然不能按照你想要的方式工作的原因是該函數在父類中不是虛擬的。但是,不可能有虛擬模板功能。

我看到兩個主要選項:

  • 爲rhalbersma建議,使類本身模板,然後覆蓋所需的方法S在子類(現在不是模板)。
  • 對於專門的方法,只需編寫一個不同名稱的新方法,即可完成您所需的任何操作。

但我敢肯定有人會想出更好的主意... =)

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

現在有定製的2種獨立的尺寸:要麼模板T,或動態類型(B對d)。對於每個模板實例,可以重新定義虛擬函數。

更常見的是讓B爲具有純虛函數(即接口)的常規類,並且讓D爲從B派生的模板類。這讓您可以以不同的方式重新定義B的虛函數D的模板實例(具有合適的默認值)。