1. 概念
模板是对类型的抽象,为了更好的实现多态的思想。
模板分为类模板和函数模板。
2. 函数模板
就是在函数之前声明一下模板,然后执行的时候,函数自行判断推导类型。
int add(int a, int b) {
return a + b;
}
double add(double a, double b){
return a + b;
}
// 如 add函数,要写多个版本
现在使用模板,只要一个函数模板就可以。
template <typename T>
T add(T a, T b){
return a + b;
}
// template 是模板声明的关键字。
// typename 是为了定义类型参数,也可以用 class。
// T 是参数类型,名字不重要。
当执行 add 时,会根据参数,自行判断类型。
3. 显式实例化和隐式实例化
显式就是说明是什么类型,隐式就是让其自行推导。
add<int>(5, 9); //显式
add(5, 9); //隐式
我声明的这个是函数模板,在执行的时候,编译期就会被实例化为一个函数,也就是模板函数。
函数模板 -------> 经过参数推导,实例化为 ------> 模板函数。
4. 特化
函数模板可以和模板函数共存,发生重载。
函数模板之间也可以发生重载。
template <typename T>
T add(T a, T b) {
cout << "T add(T, T)" << endl;
return a + b;
}
int add(int a, int b) {
cout << "int add(int, int)" << endl;
return a + b;
}
// 这种情况下,如果 add(5, 9) 运行,调用的是 int add(int, int) 的版本。
因为函数模板要推导成模板函数,现在已经有了模板函数,就直接调用模板函数了。
也就是说,模板函数优先级高于函数模板。 模板函数 > 函数模板。
但,怎么知道这是一个模板函数?表示它是函数模板的一个特例?
// 前面加上一个 template <> 表示它是函数模板的一个特化版本即可。
template <>
int add(int a, int b) {
cout << "int add(int, int)" << endl;
return a + b;
}
5. 非类型参数
模板中存在一种非类型参数。可以当作形参使用。
template <typename T, int num = 10>
T mul(T elem) {
return elem * num;
}
// 此中的 num 就是一个非类型参数。注意,非类型参数只能是整型。 double, float 不行。
6. 可变参数
类型可以声明多个,参数也可以声明多个。
如:
// 多个类型 和 形参
template <typename T1, typename T2, typename T3>
void demo(T1 t1, T2 t2, T3 t3) {
cout << t1 << " " << t2 << " " << t3 << endl;
}
可以使用模板的可变类型参数。
template <typename ...T>
void demo(T ...elem){
// 输出 所有elem 的值可以利用递归print()
print(elem...);
}
template <typename T, typename ...Arg>
void print(T e, Arg ...args){
cout << e << " ";
print(args...);
}
void print(){
return;
}
... 在前为打包,
... 在后为解包。
7. 类模板
类模板就是在类上声明的模板。
注意,类外定义的成员要带上模板
template <typename T>
class Example {
public:
void p();
};
template <typename T>
void Example<T>::p() {
cout << endl;
}
代码:
#include <iostream>
using namespace std;
template <typename T>
T add(T a, T b) {
cout << "T add(T, T)" << endl;
return a + b;
}
int add(int a, int b) {
cout << "int add(int, int)" << endl;
return a + b;
}
template <typename T, int num = 10>
T mul(T elem) {
return elem * num;
}
// 多个类型 和 形参
template <typename T1, typename T2, typename T3>
void print(T1 t1, T2 t2, T3 t3) {
cout << t1 << " " << t2 << " " << t3 << endl;
}
template <typename T, typename... Arg>
void print(T e, Arg... args) {
cout << e << " ";
print(args...);
}
void print() {
return;
}
template <typename... T>
void demo(T... elem) {
// 输出 所有elem 的值可以利用递归print()
print(elem...);
}
template <typename T>
class Example {
public:
void p();
};
template <typename T>
void Example<T>::p() {
cout << endl;
}
void test0() {
demo(1, 2, 3, 4, 5, 9);
}
int main(int argc, char* argv[]) {
test0();
return 0;
}
标签:函数,void,elem,C++,add,template,模板
From: https://www.cnblogs.com/zxinlog/p/17583710.html