是否可以“分组”模板特例?

问题描述 投票:1回答:1

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

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());
}

有可能像这样重写模板吗?

c++ templates syntax std-pair
1个回答
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);
}
© www.soinside.com 2019 - 2024. All rights reserved.