C++模板
模板概念:泛型编程,将类型参数化,在编译阶段不指定参数类型,运行阶段动态获取参数的技术,C++中分为函数模板和类模板
语法:
template<typename T>
template -- 声明创建模板
typename -- 表明其后面的符号是一种数据类型,可以用class代替
T -- 通用的数据类型,名称可以替换,通常为大写字母
函数模板:
函数模板的语法和使用:
函数模板:建立一个通用函数,函数返回值和形参类型可不具体制定,用虚拟类型代替
template<typename T>
void mySwap(T &a,T &b){
T temp=a;
a=b;
b=temp;
}
函数模板的使用方法:
1、自动类型推导:直接调用函数,由编译器自动推导参数类型
int a=10;
int b=20;
mySwap(a,b);
2、显示指定类型:调用函数时显示指定参数类型
//2、显示指定类型
mySwap<int,int>(a, b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
函数模板和普通函数的区别:
- 普通函数调用可以发生隐式类型转换
- 函数模板,用自动类型推导,不可以发生隐式类型转换
- 函数模板,用显示指定类型,可以发生隐式类型转换
//两个整型交换
void swap04(int a, int b) {
cout << "调用swap(a,b)" << endl;
cout << typeid(a).name() << endl;
int temp = a;
a = b;
b = temp;
}
//函数模板
template<typename T>
void mySwap(T a, T b) {
cout << "调用mySwap(a,b)" << endl;
cout << typeid(a).name() << endl;
T temp = a;
a = b;
b = temp;
}
int main() {
int a = 10;
int b = 20;
short c1 = 10;
short c2 = 20;
//普通函数自动类型转换,将short转换为int类型
swap04(c1, c2);
//函数模板,自动类型推导,强制匹配不会发生自动类型转换,输出的时short 类型
mySwap(c1, c2);
//函数模板,显示指定类型,会发生自动类型转换,将short转换为int类型
mySwap<int>(c1, c2);
return 0;
}
函数模板和普通函数的调用规则:
- 函数模板和普通函数都可以实现,优先调用普通函数
- 可以通过空模板参数列表来强制调用函数模板
- 函数模板也可以重载
- 函数模板可以产生更好的匹配优先调用函数模板
void myPrint(int a, int b) { cout << "这是普通函数myPringt(int a, int b)" << endl; } template <typename T> void myPrint(T a, T b) { cout << "这是函数模板myPrint(T a, T b)" << endl; } template <typename T> void myPrint(T a, T b,T c) { cout << "这是函数模板myPrint(T a, T b,T c)" << endl; } int main() { int a = 10; int b = 20; int c = 30; //优先调用普通函数 myPrint(a, b); //空模板参数列表 myPrint<>(a, b); //模板函数重载 myPrint(a, b, c); //函数模板更好匹配,short可以转为int类型,但是函数模板T可以直接推导short类型,优先匹配函数模板 short c1 = 10; short c2 = 20; myPrint(c1, c2); return 0; }
函数模板的局限性
模板的通用性并非万能
- 传入的是数组,数组之间是不可以直接赋值的
-
template<typename T> void myswap(T a,T b) { T temp = a; a = b; b = temp; }
这个代码如果传入的是数组,无法正常使用
-
- 传入的是自定义类型,很多操作是无法进行的,如赋值,相等的比较
解决方法:
- 运算符重载
-
bool operator==(Person& p) { return this->name == p.name && this->age ==p.age ? true : false; }
- 利用具体化Person的版本实现代码,具体化优化代码
-
template<typename T> bool myCompare(T& a, T& b) { return a == b ? true : false; } template<> bool myCompare(Person &p1, Person &p2) { return p1.name==p2.name&&p1.age== p1.age? true : false; }