文章目录
- 模板
- 一、模板基本语法
- 二、函数模板
- 1.基本语法
- 2.函数模板注意事项
- 3.普通函数和函数模板区别
- 4.普通函数和函数模板调用规则
- 三、类模板
- 1.基本语法
- 2.类模板和函数模板的区别
- 3.类模板中成员函数调用时机
- 4.类模板对象做函数参数
- 5.类模板与继承
- 6.成员函数的类外实现
模板
一、模板基本语法
template <typename T>
- template – 声明创建模板。
- typename —表明其后面的符号是一种数据类型,可使用class代替。
- T —通用的数据类型,名称可以替换,通常用大写字母。
二、函数模板
1.基本语法
template<typename T>
void swap(T& a,T& b)
{
T temp = a;
a = b;
b = a;
}
使用这个模板,有2种调用方法。
//1.自动类型推到
int a = 10;
int b = 20;
swqp(a,b);
//2.显示指定数据类型
swap<int>(a,b);
2.函数模板注意事项
- 自动类推导,必须推导出相同的数据类型,才可以使用。
- 模板必须确定数据类型T才可以使用。
3.普通函数和函数模板区别
- 普通函数调用时可以实现隐式类型转换。
- 函数模板使用自动类型推导,不可以实现隐式类型转换。
- 函数模板使用显示指定类型,可以实现隐式类型转换。
普通函数 | 函数模板-自动类型推导 | 函数模板-显示指定类型 | |
---|---|---|---|
隐式类型转换 | √ | × | √ |
4.普通函数和函数模板调用规则
- 如果函数模板和普通函数都可以调用,优先调用普通函数。
- 可以使用空模板参数列表,调用模板函数。
- 函数模板可以发生函数重载。
- 如果函数模板可以产生更好的匹配,优先调用函数模板。
void print(int a,int b)
{
cout << "普通函数" << endl;
cout << a << endl;
cout << b << endl;
}
template<typename T>
void print(T a,T b)
{
cout << "模板函数" << endl;
cout << a << endl;
cout << b << endl;
}
template<typename T>
void print(T a,T b,T c)
{
cout << "模板函数" << endl;
cout << a << endl;
cout << b << endl;
cout << c << endl;
}
int main()
{
int a = 10;
int b = 20;
//调用普通函数
print(a,b);
//调用模板函数
print<>(a,b);
//函数重载
print(a,b,10);
return 0;
}
三、类模板
1.基本语法
template <typename T,typename Y>
class Persion
{
public:
T name;
Y age;
};
2.类模板和函数模板的区别
- 类模板没有自动类型推导的使用方式。
- 类模板在模板参数列表中可以有默认参数。
//带有默认参数
template<typename T, typename Y = int>
class Person
{
public:
T name;
Y age;
};
3.类模板中成员函数调用时机
类模板中的成员函数在调用时才创建。
4.类模板对象做函数参数
template<typename T1, typename T2>
class Person
{
public:
T1 name;
T2 age;
};
- 指定传入的类型(最常用)
void test0(Person<string, int>& p)
{
.....
}
- 参数模板化
template<typename T1,typename T2>
void test1(Person<T1,T2>& p)
{
....
}
- 整个类模板化
template<typename T>
void test2(T& p)
{
....
}
5.类模板与继承
- 当子类继承的父类是一个类模板时,子类在声明的时候,要指出父类的类型。
- 如果不指定,编译器无法给子类分配内存。
- 如果想灵活指定父类中T的类型,子类也需变为类模板。
template<typename T>
class Base
{
T name;
};
//指定父类的类型
class Son:public Base<int>
{
};
//子类变为模板类
template<typename T>
class Son :public Base<T>
{
};
6.成员函数的类外实现
template<typename T1,typename T2>
class Person
{
public:
T1 name;
T2 age;
void show();
};
//成员函数类外实现
template<typename T1,typename T2>
void Person<T1,T2>::show()
{
....
}