2011-10-04 69 views
5

說我有這樣的:模板專用參數

template<typename T, int X> 
class foo 
{ 
public: 
    void set(const T &t); 
}; 

template<typename T, int X> 
void foo::set<T, X>(const T &t) 
{ 
    int s = X; 
    // ...etc 
} 

我可以專門功能型「T」,但留下「X」作爲模板參數?

class bar; 

template<int X> 
void foo::set<bar, X>(const bar &t) 
{ 
    int s = X; 
    // ...etc 
} 

這可能嗎?

+1

'void foo :: set (const T&t)' - >'void foo :: set(const T&t)' –

回答

6

這是非常容易的,一旦你熟悉了它

template<typename T, int X> 
class foo 
{ 
private: 
    template<typename, int> class params { }; 

public: 
    void set(const T &t) { 
    set(t, params<T, X>()); 
    } 

private: 
    template<typename T1, int X1> 
    void set(const T1 &t, params<T1, X1>) { 
    // ... 
    } 

    template<int X1> 
    void set(const bar &t, params<bar, X1>) { 
    // ... 
    } 
}; 

這是必要的,因爲如果你明確地專注一個成員,你必須提供所有模板參數的竅門。你不能離開一些。

+0

這是正確的,但我個人會避免這種詭計。它使代碼不可讀。根據具體情況(例如,創建基類模板並部分專門化它並在非專用的派生類中實現(很多?)非專用函數),IMO對該類的部分專業化或類似情況是更好的決策。 –

+0

@Serge部分專業化專業全班。所以如果他只想要一個功能的特殊行爲是不合適的。創建一個基本模板會更加噪音和不便(您將無法訪問「foo」的成員,...)。如果你有一個更清潔的解決方案,我歡迎你發佈。 –

+0

「部分專業化專業全班」 - 真實。 「創建一個基本模板會帶來更多的噪音和不便」 - 通常這不會造成不便 - 這是使體系結構保持一致的額外工作。如果需要專業化,那麼通常會有一些關於這種情況的特殊邏輯,可能需要單獨的(基礎)專業化。如果有大量的通用成員對象,那麼將它們(保護)放在另一個類中作爲父專業化的基礎(通常這裏有一個邏輯)是沒有問題的。 –

2

不,這是不允許的。 A class成員函數必須完全專用。例如,它應該是,

template<> 
void foo<bar, 5>::set(const bar &t) 
{   //^^^^ 
    int s = 5; 
    // ...etc 
} 
1

你可以部分專門化整個班級。在這種情況下,您可以針對該類的每個專業化實現set函數的不同實現。

+0

你能舉個例子嗎? – MarkP

+0

@MarkP,檢查[this](http://stackoverflow.com/questions/1535816/c-partial-method-specialization/1535845#1535845)回答。 –

3

你可以考慮重寫你的代碼,以使成員函數一個單獨的模板:

template <int X> class foo 
{ 
    template <typename T> void set(const T &); 
    // ... 
}; 

然後,你可以爲模板foo<X>::set提供明確的專業。