2015-07-21 4 views
1

Например, у меня есть функция шаблона, используемая для итерации вектора в векторе:Можно ли «сгруппировать» специальный шаблон?

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

, который имеет пару, как частный случай, который типом пары может быть двойной, с плавающей точкой, INT, строкой ...:

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); 
} 
Смежные вопросы