2009-08-23 58 views
7

的模板特我想專攻以下成員函數:模板類

class foo { 
    template<typename T> 
    T get() const; 
}; 

要取決於模板以及其他類bar

例如,我想barstd::pair一些模板參數,這樣的事情:

template<> 
std::pair<T1,T2> foo::get() const 
{ 
    T1 x=...; 
    T2 y=...; 
    return std::pair<T1,T2>(x,y); 
} 

其中T1和T2是模板爲好。如何才能做到這一點?據我所知應該是 可能。

所以,現在我可以打電話:

some_foo.get<std::pair<int,double> >(); 

全/最後的答案:

template<typename T> struct traits; 
class foo { 
    template<typename T> 
    T get() const 
    { 
     return traits<T>::get(*this); 
    } 
}; 

template<typename T> 
struct traits { 
    static T get(foo &f) 
    { 
     return f.get<T>(); 
    } 
}; 

template<typename T1,typename T2> 
struct traits<std::pair<T1,T2> > { 
     static std::pair<T1,T2> get(foo &f) 
     { 
       T1 x=...; 
       T2 y=...; 
       return std::make_pair(x,y); 
     } 
}; 
+0

目前尚不清楚你的意思。你想要一個適用於T1和T2是模板的專業化嗎?或者當他們是一些特定的模板?或者當他們是模板時,他們的參數是一些特定的類型? – jalf 2009-08-23 12:41:31

+0

我的意思是說,我想將我的函數專門化爲其他特定類型(如std :: pair),它也需要一些模板參數。 – Artyom 2009-08-23 12:47:00

+0

請檢查此:http://stackoverflow.com/questions/947943/template-specialisation-where-templated-type-is-also-a-template – 2009-08-23 12:52:20

回答

8

不能部分專門函數模板,對不起,但這些是規則。你可以這樣做:

class foo { 
    ... 
}; 


template<typename T> 
struct getter { 
    static T get(const foo& some_foo); 
}; 

template<typename T1, typename T2> 
struct getter< std::pair<T1, T2> > { 
static std::pair<T1, T2> get(const foo& some_foo) { 
    T1 t1 = ...; 
    T2 t2 = ...; 
    return std::make_pair(t1, t2); 
}; 

,然後調用它像

getter<std::pair<int, double> >::get(some_foo); 

雖然。如果get確實需要成爲會員功能,則您可能需要對friend船舶或能見度做一些調整。

爲了詳細說明SBI的建議:

class foo { 
    ... 
    template<typename T> 
    T get() const; 
}; 

template<typename T> 
T foo::get() const 
{ 
    return getter<T>::get(*this); 
    /*   ^-- specialization happens here */ 
} 

而現在你又回到了能說

std::pair<int,double> p = some_foo.get<std::pair<int, double> >(); 
+1

你可以。但是,使'getter'成爲該類的一個(可能是'private')成員,並通過一個普通的成員函數模板進行調用。這樣,你的班級的用戶就不必關心這個機制。 – sbi 2009-08-23 19:21:47

+0

@sbi,這是一個偉大的觀點。 – 2009-08-23 19:42:28

1

你需要重載爲對你的成員函數,像

template <T, V> std::pair<T, V> foo::get() 

在一般情況下,您需要能夠消除各種過載之間的歧義。在消歧很容易的情況下,因爲對以2種類型爲模板,而原始成員僅在T上模板化。

如果您需要針對例如std :: vector進行專門化,即針對具有單個參數模板的容器,則必須小心謹慎,因爲如果希望編譯器理解您是否希望實例化模板特在模板T爲標準::向量或過載的專業化,

template <T> std::<vector <T> foo::get() const 

你提出的語法不能工作,因爲你是完全專業的成員函數,

template <>

,但你沒有列出兩個未指定的類型,T1和T2。

+0

這是行不通的:「原型爲std :: pair <_T1, _T2> foo :: get()'與類foo中的任何一個都不匹配;應聘者是:template T foo :: get()」 – Artyom 2009-08-23 13:49:48

+0

你必須在類foo中聲明 'template std :: pair get()const;' 然後稱之爲: 'std :: pair p_int = f.get (); ' – Francesco 2009-08-23 14:48:05