C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)
转自:https://www.cnblogs.com/zhoug2020/p/6581477.html
模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数。类模板中大多数成员函数的功能可能是一模一样的,特化时我们可能只需要重新实现1、2个成员函数即可。在这种情况下,如果全部重写该模板类的所有成员函数,不但会增加工作量,也不利于代码的维护。
例如下面的类模板A,只有在模板参数是char*时才需要特化成员函数func(),但其他的成员函数都不需要特化:
1 template <typename _Ty> 2 struct A 3 { 4 // 其他成员函数a 5 // 其他成员函数b 6 // ...... 7 void func() 8 { 9 std::cout << "common type." << std::endl; 10 } 11 }; 12 13 int main() 14 { 15 A<int> i; 16 i.func(); 17 18 A<char*> c; 19 c.func(); 20 21 return 0; 22 }
方法一:通过运行时类型识别,这个方法最简单
1 template <typename _Ty> 2 struct A 3 { 4 // 其他成员函数a 5 // 其他成员函数b 6 // ...... 7 void func() 8 { 9 if (typeid(_Ty) == typeid(char*)) 10 std::cout << "common type." << std::endl; 11 else 12 std::cout << "special type." << std::endl; 13 } 14 };
方法二:通过类的成员函数模板特化来实现,这个方法也比较简单
1 template <typename _Ty> 2 struct A 3 { 4 // 其他成员函数a 5 // 其他成员函数b 6 // ...... 7 template <typename __Ty> 8 void funcImpl() 9 { 10 std::cout << "common type." << std::endl; 11 } 12 13 template <> 14 void funcImpl<char*>() 15 { 16 std::cout << "special type." << std::endl; 17 } 18 19 void func() 20 { 21 funcImpl<_Ty>(); 22 } 23 };
方法三:通过一个嵌套模板类的特化来实现
1 template <typename _Ty> 2 struct A 3 { 4 // 其他成员函数a 5 // 其他成员函数b 6 // ...... 7 template <typename __Ty> 8 struct IsCharPType 9 { 10 const static bool b = false; 11 }; 12 13 template<> 14 struct IsCharPType<char*> 15 { 16 const static bool b = true; 17 }; 18 19 void func() 20 { 21 if (IsCharPType<_Ty>::b) 22 std::cout << "special type." << std::endl; 23 else 24 std::cout << "common type." << std::endl; 25 } 26 };
方法四:先定义一个嵌套的类模板,通过重载函数实现(函数的参数类型不同
1 template <typename _Ty> 2 struct A 3 { 4 // 其他成员函数a 5 // 其他成员函数b 6 // ...... 7 template <typename __Ty> 8 struct TypeClass 9 { 10 }; 11 12 template <typename __Ty> 13 void funcImpl(const TypeClass<__Ty>&) 14 { 15 std::cout << "common type." << std::endl; 16 } 17 18 void funcImpl(const TypeClass<char*>&) 19 { 20 std::cout << "special type." << std::endl; 21 } 22 23 void func() 24 { 25 funcImpl(TypeClass<_Ty>()); 26 } 27 };