模板:实现与类型无关的通用代码
函数的模板特化:
必须要有一个基础的函数模板
关键字template后面接一对空的尖括号<>
函数名后面加以对尖括号,尖括号中指定需要特化的类型
函数形参表:必须要和模板函数的基础参数类型完全相同,如果不同扁你其肯回报一些奇怪的错误
函数模板不建议特化 直接写一个普通函数即可
非类型模板参数:类似乐一看作常量的参数,一般是整型
字符串常量 字符串常量 自定义对象 不行
类的模板特化
全特化:将模板参数类表中所有的参数全部确定
template<class T1, class T2>
class Data
{
public:
Data()
{
cout << "<T1, T2>" << endl;
}
private:
T1 _d1;
T2 _d2;
};
template<>
class Data<int, char>
{
public:
Data()
{
cout << "<int, char>" << endl;
}
private:
int _d1;
char _d2;
};
int main()
{
Data<int, int> a;
Data<int, char> b;
system("pause");
return 0;
}
//偏特化:任何针对模板参数进一步进行条件限制设计的特化版本
//两种表现方式
//部分特化 将模板参数类表中的一部分参数特化
template<class T1>
class Data<T1, int>
{
public:
Data()
{
cout << "Data<T1, int>" << endl;
}
private:
T1 _d1;
int _d2;
};
参数进一步的限制 偏特化不仅仅是指特化部分参数 而是针对模板参数更进一步的条件限制所设计出来的一个特化版本
//俩个参数偏特化为指针类型
template<class T1, class T2>
class Data<T1*, T2*>
{
public:
Data()
{
cout << "<T1*, T2*>" << endl;
}
private:
T1* _d1;
T2* _d2;
};
//将俩个参数偏特化为引用类型
template<class T1, class T2>
class Data<T1&, T2&>
{
public:
Data(const T1& d1, const T2& d2)
:_d1(d1)
,_d2(d2)
{
cout << "<T1&, T2&>" << endl;
}
private:
const T1& _d1;
const T2& _d2;
};
//求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句
//累加
//特殊:编译时递归
template<size_t N>
class Sum
{
public:
enum{RET = Sum<N-1>::RET + N};
};
template<>
class Sum<1>
{
public:
enum { RET = 1 };
};
int main()
{
//默认最高递归次数为500次 所以Sum<501>会出错 由于Sum<1>
//不用递归 所以Sum<500>可以通过
cout << Sum<10>::RET << endl;
system("pause");
return 0;
}
类型萃取:基础模板与特化模板的结合使用 目的是分流 将不同种类的类型分开处理(例:
自定义类型 与 内置类型)
实现步骤:
定义俩个结构体 falsetype truetype
定义类模板
类特化
应用:拷贝
//代表内置类型
struct TrueType
{
static bool Get()
{
return true;
}
};
//代表自定义类型
struct FalseType
{
static bool Get()
{
return false;
}
};
template<class T>
struct TypeTraits
{
typedef FalseType isPODType;
};
template<>
struct TypeTraits<char>
{
typedef TrueType isPODType;
};
template<>
struct TypeTraits<short>
{
typedef TrueType isPODType;
};
template<>
struct TypeTraits<int>
{
typedef TrueType isPODType;
};
template<>
struct TypeTraits<long>
{
typedef TrueType isPODType;
};
template<>
struct TypeTraits<long long>
{
typedef TrueType isPODType;
};
template<>
struct TypeTraits<float>
{
typedef TrueType isPODType;
};
template<>
struct TypeTraits<double>
{
typedef TrueType isPODType;
};
template<>
struct TypeTraits<long double>
{
typedef TrueType isPODType;
};
template<class T>
void Copy2(T* dst, const T* src, size_t size)
{
if (TypeTraits<T>::isPODType::Get())
{
memcpy(dst, src, sizeof(T)*size);
cout << "浅" << endl;
}
else
{
for (size_t i = 0; i < size; ++i)
{
dst[i] = src[i];
}
cout << "深" << endl;
}
}
int main()
{
int a1[] = { 1,2,3,4,5,6,7,8,9,0 };
int a2[10];
Copy2(a2, a1, 10);
string s1[] = { "1111", "2222", "3333", "4444" };
string s2[4];
Copy2(s2, s1, 4);
system("pause");
return 0;
}