2011-08-08 72 views
16

是否有可能擁有僅在所採用的模板參數數量方面不同的相同類的多個版本?通過模板參數編號重載模板類

例如:

template<typename T> 
class Blah { 
public: 
    void operator()(T); 
}; 

template<typename T, typename T2> 
class Blah { 
public: 
    void operator()(T, T2); 
}; 

我試圖模擬仿函數類的東西,可以採取可變數目的參數(最多的是人寫出來的不同模板的數量)。

+0

我想知道,如果你可以做一些類型串。 – john

+0

@john這將是一個好主意,但我使用的MSVC++ 2010不支持他們,我不相信。 –

+0

實際上,boost :: tuple可能是同一個想法的更易訪問的版本。擁有一種類型的通用模板,然後是具有2,3,4 ...類型元組的專用版本。 – john

回答

22

最簡單的答案是隻有一個模板,其中包含您希望支持的最大數量,並且對除第一個類型之外的所有類型都使用默認類型使用void。然後,你可以根據需要使用的部分專業化:

template<typename T1, typename T2=void> 
struct foo { 
    void operator()(T1, T2); 
}; 

template <typename T1> 
struct foo<T1, void> { 
    void operator()(T1); 
}; 

int main() { 
    foo<int> test1; 
    foo<int,int> test2; 
    test1(0); 
    test2(1,1); 
} 
+1

我不認爲'operator()(T,T2,T3,T4)'的定義在某些類型爲'void'的情況下可以正常工作。 –

+0

@你說得對,沒有,我已經試過了。 –

+2

@ben - 它不這樣工作,因此部分專業化有效地給模板參數的數量「重載」 – Flexo

14

一個模板只能有一個基地定義。如果您需要可變數量的參數並且您不想使用「空類型」結構,並且您使用的是C++ 0x編譯器,那麼您可以使用可變參數模板:

template <typename ...Dummy> struct foo; // base case, never instantiated! 

template <typename T> struct foo<T> { /*...*/ }; // partial spec. for one parameter 
template <typename T, typename U> struct foo<T, U> { /*...*/ }; // ditto for two 
0

這是未經測試的代碼,我沒有一個版本提升得心應手,但在這裏不用反正

#include "boost/tuple.h" 

template <class T> 
class Blah; 

template <class T> 
class Blah< boost::tuple<T> > 
{ 
    void operator()(T arg); 
}; 

template <class T, class U> 
class Blah< boost::tuple<T, U> > 
{ 
    void operator()(T arg1, U arg2); 
}; 

等等,等等