有可能" group"模板特例?

时间:2015-07-21 02:48:18

标签: c++ templates syntax std-pair

例如,我有一个模板函数用于迭代向量中的向量:

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

其中有一对作为特例,其对类型可以是double,float,int,string,...:

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 个答案:

答案 0 :(得分: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);
}