例如,我有一个模板函数用于迭代向量中的向量:
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());
}
是否可以像这样重写模板?
答案 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);
}