目录
第三章 STL
模板参数
模板参数分为类型形参与非类型形参。
模板又分为类型模板和非类型模板。
类型模板
类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
#define N1 100
// 类型模板
template<class T>
class array1 // 官方的STL容器中array是固定长度的数组
{
public:
private:
T _a[N1];
};
非类型模板
非类型形参:指定具体类型的一个参数,在类(函数)模板中可将该参数当成常量来使用。
浮点型和自定义类型不可以
// 非类型模板
// 浮点型和自定义类型 不可以
//template<class T, double D>
//template<class T, string D>
template<class T,int N> // long long/ long/ int /short / char 整形 是常量
class array2
{
public:
private:
T _a[N];
};
模板的特化
通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理
函数模板的特化
// 模板的特化
template<class T >
bool IsEqual(T& left, T& right)
{
return left == right;
}
// 特化(针对某些类型的特殊化处理)
template<>
bool IsEqual<char*>(char*& left, char*& right)
{
return strcmp(left,right);
}
intmain()
{
array2<int, 100> a1;
int a = 1, b = 0;
cout << IsEqual(a, b) << endl;
const char* s1= "hello";
const char* s2= "world";
cout << IsEqual(s1, s2) << endl;
}
类模板的特化
类模板特化有全特化和偏特化两种,就跟缺省值有全缺省和半缺省一样(联系起来记住)
template<class T1,class T2>
class Date
{
public:
Date() { cout << "Date<T1,T2>" << endl; }
};
// 全特化 全部参数都特化
template<> // 出现的每一句这个都是不能少的哈
class Date<int,int>
{
public:
Date() { cout << "全特化:Date<int , int>" << endl; }
};
// 偏特化 可以是特化部分参数或者对参数进行限制
template<class T2>
class Date<int,T2> // 参数顺序是有影响的
{
public:
Date() { cout << "偏特化:Date<int , T2>" << endl; }
};
template<class T1,class T2>
class Date<T1*, T2*> // 都是指针就匹配这个
{
public:
Date() { cout << "偏特化:Date<T1*, T2*>" << endl; }
};
template<class T1, class T2>
class Date<T1&, T2&> // 都是引用就匹配这个
{
public:
Date() { cout << "偏特化:Date<T1&, T2&>" << endl; }
};
int main()
{
Date<int, char> d1; // 偏特化:Date<int , T2>
Date<int, int> d2; // 全特化:Date<int , int>
Date<char, int> d3; // Date<T1,T2>
reuturn 0;
}
只要有与全特化具体指明的类型一一对应,一定优先调用全特化,偏特化有对应具体类型的相同且与全特化不匹配,结果就是优先调用偏特化。
模板的分离编译
由于模板是在使用时才实例化,当模板的声明与定义分离开,即在头文件中进行声明,源文件中完成定义,在编译时会报错的,所以有一种解决方案,但不建议用
// func.h
void f1();
template<class T>
void f2(const T& s);
// func.cpp
#include<iostream>
using namespace std;
#include"func.h"
void f1()
{
cout << "f1()" << endl;
}
template<class T>
void f2(const T& s)
{
cout << s << endl;
}
// 解决模板不能分离编译的方法;
// 1.显示实例化,不常用,因为不方便
// 2.粗暴一点,不要分离编译,
template
void f2<int>(const int& a);
template
void f2<double>(const double& a);
一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。
总结
优点
1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生
2. 增强了代码的灵活性
缺陷
1. 模板会导致代码膨胀问题,也会导致编译时间变长
2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误