2011-10-17 207 views
3

我想專用模板類中的特定功能。C++模板:部分模板模板類中的功能專業化

如:

template<class T> 
class A 
{  
public : 
    void fun1(T val); 
    void fun2(T val1, T val2); 
}; 

template <class T> 
void A<T>::fun1(T val) 
{ 
    // some task 1; 
} 


template <class T> 
void A<T>::fun2(T val1, T val2) 
{ 
    // some task 2; 
} 


template <> 
void A<char*>::fun2(char* val1, char* val2) 
{ 
    // some task 2 specific to char*; 
} 

當我做這樣的事情,我得到錯誤說的FUN2多個定義() 請讓我爲什麼這個錯誤的,也是正確的方式來實現這一點。

+0

編譯和我[http://ideone.com/zTdcB](鏈接成功http://ideone.com/zTdcB)。 – ks1322

+1

@ ks1322,那是因爲你沒有在ideone中涉及多個文件。您可以嘗試在.h文件中聲明此代碼,然後將其包含在2個.cpp文件中。你會得到鏈接錯誤。 – iammilind

+0

@Rahul重定義錯誤(取決於編譯器)是由於這樣一個事實,即在你的完全專業化(又稱顯式專業化)中,你提供了一個模板參數char *,當這個參數在主模板初始化時被替換,那麼fun2已經decl/def和T將被替換char * –

回答

2

你的方法fun2()不是template方法本身,雖然這是一個template類的成員。我找不到合適的技術術語,但用簡單的話來說,專門的fun2()將產生正常功能定義的效果。將定義放在頭文件中會給你多重定義錯誤。

爲了解決這個問題,只是把一個inline關鍵字和鏈接器錯誤將消失!

template <> inline // <----- 'inline' will prompt to generate only 1 copy 
void A<char*>::fun2(char* val1, char* val2) 
{ 
    // some task 2 specific to char*; 
} 

編輯:這解決了連接錯誤。但仍然不能使用A<char*>::fun2。最終它歸結爲張女士您需要專門整個class A<char*>超載的內A<T>

template<class T> 
class A 
{ 
    // constructors 
public: 
    //... 
    void fun2(char* val1, char* val2) 
    { 
    //specific case when T = char* 
    } 
}; 
+0

謝謝..我工作。 – Rahul

4

我會建議採用以下方法。定義一個名爲implementation來處理一般情況下的private功能模板,超載專門implementation處理具體案件時T=char*。然後從fun2(),調用implementation傳遞第三個參數,如下所示。正確implementation將根據模板參數T選擇:

template<class T> 
class A 
{  
    template<typename U> struct selector{}; 

    public : 
     void fun1(T val); 
     void fun2(T val1, T val2) 
     { 
      //forward the call 
      //a correct function will be selected automatically based on T 
      implementation(val1, val2, selector<T>()); 
     } 
    private: 
     template<typename U> 
     void implementation(T & val1, T & val2, const selector<U> &) 
     { 
      //general case! 
     } 
     void implementation(T & val1, T & val2, const selector<char*> &) 
     { 
      //specific case when T = char* 
     } 
}; 

selector<T>型(或selector<char*>)的第三個參數有助於選擇正確的實現。

+1

,我相信這是最好的方法,儘管有些人喜歡提供不同的專業化+1。 –

1

相應的分割你的代碼,它應該工作,例如:

template<class T> 
class A 
{  
    public : 
     void fun1(T val); 
     void fun2(T val1, T val2); 

}; 

template <class T> 
void A<T>::fun1(T val) 
{ 
    // some task 1; 
} 


template <class T> 
void A<T>::fun2(T val1, T val2) 
{ 
    // some task 2; 
} 

A.cpp

#include <iostream> 
#include "A.h" 

template <> 
void A<char *>::fun2(char* val1, char* val2) 
{ 
    // some task 2 specific to char*; 
    std::cout << "char*::fun2" << std::endl; 
} 

Amain.cpp

#include <iostream>  
#include "A.h" 

int main() 
{ 
    A<char*> a; 

    char* c= 0; 
    char* d= 0; 

    a.fun2(c, d); 
} 

編譯和鏈接,它應該做的事...

+0

嗨,感謝您的回覆。我只是做了fun2()內聯並運行良好。 – Rahul