2015-07-21 21 views
1

例如,我有用於矢量迭代向量的模板函數:是否有可能「分組」模板特殊情況?

template<class T> 
void test(T t){ 
    for(auto tt : t){ 
     test(tt); 
    } 
} 

其具有一對作爲特殊的情況,其中一對類型可以是雙,浮動,整型,字符串,...:

pair<double,double> 
pair<double,float> 
pair<double,int> 
pair<double,string> 
pair<float,double> 
pair<float,float> 
pair<float,int> 
pair<float,string> 
pair<int,double> 
pair<int,float> 
pair<int,int> 
pair<int,string> 
pair<string,double> 
pair<string,float> 
pair<string,int> 
pair<string,string> 

模板可以做一些工作,這pair.first獨立pair.second的(可能是添加元素,JSON,寫入文件,...現在用printf來表示):

template<> 
void test(pair<double,double> p){ 
    printf("%f,",p.first); 
    printf("%f\n",p.second); 
} 

template<> 
void test(pair<double,float> p){ 
    printf("%f,",p.first); 
    printf("%f\n",p.second); 
} 
. 
. 
. 

代碼工作,但是模板函數的數量是可怕的,因爲它需要16個模板,是可以分離和組模板特殊情況下,第一和第二,這樣就需要8個模板僅是這樣的:

pair<double,T> 
pair<float,T> 
pair<int,T> 
pair<string,T> 
pair<T,double> 
pair<T,float> 
pair<T,int> 
pair<T,string> 

我嘗試以下,但無法編譯:

template<class SECOND> 
void test(pair<double,SECOND> p){ 
    printf("%f,",p.first); 
    test<double,SECOND>(p); 
} 

template<class SECOND> 
void test(pair<float,SECOND> p){ 
    printf("%f,",p.first); 
    test<double,SECOND>(p); 
} 
. 
. 
. 
template<class FIRST> 
void test(pair<FIRST,int> p){ 
    printf("%d\n",p.second); 
} 

template<class FIRST> 
void test(pair<FIRST,string> p){ 
    printf("%s\n",p.second.c_str()); 
} 

是否有可能重寫模板是這樣的?

回答

1
namespace details { 
    template<class T> 
    using is_wanted_type = 
      std::integral_constant<bool, std::is_same<int, T>{} 
             || std::is_same<float, T>{} 
             || std::is_same<double, T>{} 
             || std::is_same<std::string, T>{}>; 

    void process_first(int) { /* ... */ } 
    void process_first(float) { /* ... */ } 
    void process_first(double) { /* ... */ } 
    void process_first(const std::string &) { /* ... */ } 

    void process_second(int) { /* ... */ } 
    void process_second(float) { /* ... */ } 
    void process_second(double) { /* ... */ } 
    void process_second(const std::string &) { /* ... */ } 
} 

template<class T1, class T2> 
std::enable_if_t<details::is_wanted_type<T1>{} && details::is_wanted_type<T2>{}> 
test(const std::pair<T1, T2> &p) { 
    details::process_first(p.first); 
    details::process_second(p.second); 
}