一.模板函数
#include <iostream>
using namespace std;
template<class T>//声明一个class类型为T的类,防止编译器报错
void mySwap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
int main(int argc, const char * argv[]) {
int a = 10;
int b = 20;
mySwap(a, b);//自动类型推导,必须有参数类型才可以推导
mySwap<int>(a, b);//显示指定类型
cout << "a:" << a << "b:" << b << endl;//a:20b:10
return 0;
}
第三代具体化自定义数据类型
//
// main.c
// cdemo
//
// Created by liyongkai on 2021/6/6.
//
#include <iostream>
using namespace std;
class Person{
public:
Person(string name) {
this->name = name;
}
string name;
};
template<class T>//声明一个class类型为T的类,防止编译器报错
bool isEquel(T &a, T &b) {
if (a == b) {
return true;
}
return false;
}
template<> bool isEquel<Person>(Person &a, Person &b) {
if (&a == &b) {
return true;
}
return false;
}
int main(int argc, const char * argv[]) {
//没有问题
int a = 10;
int b = 20;
bool i = isEquel(a, b);
cout << i << endl;//0
//如果直接比较两个对象,会报错
//Invalid operands to binary expression ('Person' and 'Person')
//会走template<> bool isEquel(Person &a, Person &b) 这个方法
Person p1("111");
Person p2("222");
isEquel(p1, p2);
bool ii = isEquel(a, b);
cout << ii << endl;//0
return 0;
}
二.模板函数与普通函数优先级
- 如果存在同名的模板函数和普通函数,编译器会优先调用普通函数,如果普通函数没有实现则会报错
- 如果想要强制调用模板函数,那么可以使用空参数列表
myPrint<>(a, b)
,加个<>
- 模板也可以重载
三.模板实现机制
- 编译器并不是把函数模板编译成能够处理任意类型的函数
- 函数模板通过具体类型生成不同的函数
- 编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行再次编译
四.类模板
#include <iostream>
using namespace std;
template <class nameType, class ageType = int> //ageType = int 类模板可以有默认类型
class Person{
public:
nameType name;
ageType age;
Person(nameType name, ageType age) {
this->name = name;
this->age = age;
}
};
int main(int argc, const char * argv[]) {
//Use of class template 'Person' requires template arguments
//Person p1("tom", 100);
Person<string, int> p1("tom", 100);
return 0;
}
五.类模板的成员函数
- 类模板的成员函数一开始不会被创建出来,只有运行的时候才去创建
六.模板类继承问题
- 如果基类是模板类,必须让子类告诉编译器 基类中的T到底是什么类型。如果不告诉,那么无法分配内存,编译不通过
class Child:public Base<int>
- .hpp文件一般都是模板类
网友评论