模板类的特化:
有时为了需要,针对特定的类型,需要对模板进行特化,也就是所谓的特殊处理。
全特化 :对传入的数据类型都做了限制
偏特化(半特化):偏特化并不仅仅是指特殊部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。
模板的全特化和偏特化都是在已定义的模板基础之上,不能单独存在。
template <typename T1, typename T2> class Data { public: Data() { cout << "Data<T1, T2>" << endl; } }; template <> class Data<int , int> { public: Data() { cout << "Data<int, int>" << endl; } }; ////全特化 > 局部特化 > 无特化版本 ; 匹配最匹配的 //// 模板的全特化和偏特化都是在已定义的模板基础之上,不能单独存在 template <class T> class Data<T, int> { public: Data() { cout << "Data<T, int>" << endl; } }; template <class T1, class T2> class Data<T1*, T2*> { public: Data() { cout << "Data<T1*, T2*>" << endl; } }; template <class T1, class T2> class Data<T1, T2*> { public: Data() { cout << "Data<T1, T2*>" << endl; } }; template <class T1, class T2> class Data<T1&, T2&> { public: Data() { cout << "Data<T1&, T2&>" << endl; } }; void test1() { Data<char, char> d; // T T Data<int, char> d1; // T T Data<int, int> d2; // int int Data<char, int> d3; // T int Data <int*, int*> d4; // int* int* Data <int, int*> d5; // T int* Data <int&, int&> d6; // int& int& }
类模板特化的应用:类型萃取
对指定的类型使用特定的处理方式。
#pragma once #include <iostream> #include <string> using namespace std; struct __TrueType {}; struct __FalseType {}; // POD: plain old data 平凡类型(无关痛痒的类型)--基本类型 // 指在C++ 中与 C兼容的类型,可以按照 C 的方式处理。 template <class T> struct TypeTraits { typedef __FalseType IsPodType; }; template <> struct TypeTraits< bool> { typedef __TrueType IsPodType; }; template <> struct TypeTraits<int> { typedef __TrueType IsPodType; }; template <> struct TypeTraits<char> { typedef __TrueType IsPodType; }; template <> struct TypeTraits<long long> { typedef __TrueType IsPodType; }; template <> struct TypeTraits<short> { typedef __TrueType IsPodType; }; template <> struct TypeTraits<double> { typedef __TrueType IsPodType; }; //template <> //struct TypeTraits<Date> //Date为自定义类型 ,当我们要用特定的方式处理自定义类型时,也可以这样做 //{ // typedef __TrueType IsPodType; //}; template <class T> inline T* __TypeCopy(const T* src, T* dst, size_t n, __TrueType) //普通类型(声明了的) memcpy { cout << "memcpy " << typeid(T).name() << endl; return (T*)memcpy(dst, src, sizeof(T) * n); } template <class T> inline T* __TypeCopy(const T* src, T* dst, size_t n, __FalseType) //非普通类型 for, 与上面的构成重载 { cout << "for + operator= " << typeid(T).name()<< endl; for (size_t i = 0; i < n; i++) { dst[i] = src[i]; } return dst; } template <class T> inline T* TypeCopy(const T* src, T* dst, size_t n) { return __TypeCopy(src, dst, n, TypeTraits<T>::IsPodType()); } void TestTypeCopy() { string s1[3] = { "11", "22", "33" }; string s2[3] = { "" }; int a1[3] = { 1, 2, 3 }; int a2[3] = { 0 }; TypeCopy(s1, s2, 3); TypeCopy(a1, a2, 3); }