C++类模板偏特化
C++类模板偏特化
C++中的函数模板和类模板被广泛应用,其中函数模板只支持重载和全特化,而C++类模板支持偏特化,以下是一个例子,用于记录类模板偏特化。
一个tuple打印器
tuple_print 实现tuple数据打印
1
2
3
4
5
6
7
8
9
10
11
template<int IDX, int MAX_SIZE, typename ...Args>
struct tuple_print {
void operator()(ostream& os, const tuple<Args...> & t) {
// print idx item
os << get<IDX>(t) << (IDX == MAX_SIZE - 1 ? "" : ",");
tuple_print<IDX + 1, MAX_SIZE, Args...>()(os, t);
}
};
tuple_print 偏特化
为了让打印器能够停止递归,需要实现一个偏特化类
1
2
3
4
5
6
7
8
// 偏特化
template<int MAX_SIZE, typename ...Args>
struct tuple_print<MAX_SIZE, MAX_SIZE, Args...> {
void operator()(ostream& os, const tuple<Args...> & t) {
// do nothing
}
};
重载流运算符
1
2
3
4
5
6
template<typename ...Args>
ostream& operator<<(ostream& os, const tuple<Args...>& t) {
os << "[";
tuple_print<0, sizeof...(Args), Args...>()(os, t);
return os << "]";
}
测试程序
1
2
3
4
5
6
7
8
int main() {
tuple<int, const char*> t(3, "hhh");
cout << t << endl;
return 0;
}
输出结果
1
[3,hhh]
note
不能通过判断IDX == MAX_SIZE - 1来return的方式,C++ 模板是编译期展开的。即使这个 if 在运行时会跳过递归调用,编译器仍会尝试实例化 tuple_print<IDX+1, MAX_SIZE, Args…>,即使它永远不会被执行!所以需要通过偏特化的方式停止这个过程。
本文由作者按照 CC BY 4.0 进行授权