一、函数模板的由来和引入
假设我们需要编写一个函数来计算两个数字的和,并且需要处理不同的数据类型(如整数和浮点数),实现如下:
#include <iostream>
using namespace std;
// 处理整数的加法函数
int addInt(int a, int b) {
return a + b;
}
// 处理浮点数的加法函数
double addDouble(double a, double b) {
return a + b;
}
int main() {
// 使用处理整数的加法函数
cout << addInt(3, 4) << endl; // 输出 7
// 使用处理浮点数的加法函数
cout << addDouble(3.5, 4.5) << endl; // 输出 8.0
return 0;
}
可以看出,如果我们需要支持多个类型时,需要多个函数,而实际上我们只需要定义一个 “函数” 就能解决,经过改造后的模板函数示例如下:
#include <iostream>
using namespace std;
// 定义一个函数模板
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
// 使用模板函数处理整数
cout << add(3, 4) << endl; // 输出 7
// 使用模板函数处理浮点数
cout << add(3.5, 4.5) << endl; // 输出 8.0
return 0;
}
在这个例子中,add 函数模板可以处理不同类型的数据(如整数和浮点数)。当你调用 add(3, 4) 时,编译器会生成一个处理整数的 add 函数;当你调用 add(3.5, 4.5) 时,编译器会生成一个处理浮点数的 add 函数。
二、函数模板的定义
函数模板是C++中的一种特性,它将将参数列表中的全部或者部分参数类型剥离了出来,允许你编写一个通用的函数。
函数模板的格式包括模板声明、模板参数列表和函数定义。下面是函数模板的基本格式:
template <typename T>
返回类型 函数名(参数列表) {
// 函数体
}
- template <typename T>:这是模板声明,T 是一个类型参数。你也可以使用 class 关键字代替 typename,效果是一样的。
- 返回类型:函数的返回类型,可以是模板参数 T 或其他类型。
- 函数名:函数的名称。
- 参数列表:函数的参数列表,可以包含一个或多个模板参数 T。
三、模板参数的分类
3.1、类型参数
类型参数是最常见的模板参数,用于表示一个类型。在模板定义中,类型参数通常使用关键字 typename 或 class 来声明。
template <typename T>
T add(T a, T b) {
return a + b;
}
例如上述例子中:T 是一个类型参数,它可以被任何类型(如 int、double 等)替换。
3.2、非类型参数
非类型参数用于表示一个值,而不是类型。非类型参数可以是整型、枚举、指针或引用等。
template <typename T, int size>
class Array {
private:
T arr[size];
public:
T& operator[](int index) {
return arr[index];
}
};
在这个例子中,size 是一个非类型参数,它表示数组的大小。
四、函数模板的实现原理
#include <iostream>
using namespace std;
template<class T>
T funcT1(T a, T b){
return a+b;
}
/*
* objdump -DC a.out>c1.txt 将二进制文件以可读的方式导出(反编译)
* win dumpbin /all abc.obj>abc.txt
*
*
* 实例化
* int funcT1<int>(int, int)
* double funcT1<double>(double, double)
*
* 返回值类型 模板名<具体类型>(参数类型)
*
*
* 如果函数定义完了,但是没有调用,编译器会优化掉,同理,如果一个参数没有被使用,也会被编译器优化
*
* */
int main(){
int a=1;
int b=2;
double c=1.1;
double d=2.2;
cout<<funcT1(a,b)<<endl; // 42 <int funcT1<int>(int, int)>:
cout<<funcT1(c,d)<<endl; //91 <double funcT1<double>(double, double)>:
//cout<<funcT1<int>(c,d)<<endl;
return 0;
}
C++函数模板的详细讲解【函数模板的概念、用法及其模板函数的概念知识】_c++函数模板的定义及使用-CSDN博客
五、总结
函数模板是C++语言的一部分,最早在C++98标准中引入。随着C++标准的不断发展,模板机制也得到了不断的扩展和改进:
- C++98/03:引入了基本的模板机制,包括类模板和函数模板。
- C++11:引入了更多的模板特性,如变参模板(Variadic Templates)和模板别名(Template Aliases)。
- C++14:进一步简化了模板的使用,如泛型Lambda表达式。
- C++17:引入了模板参数推导(Template Argument Deduction)和折叠表达式(Fold Expressions)。
- C++20:引入了概念(Concepts),进一步增强了模板的表达能力和类型约束。
通过引入函数模板,C++成功地实现了类型安全和代码重用,极大地提高了编程的灵活性和效率。函数模板的引入使得C++成为一种强大且灵活的编程语言,广泛应用于各种软件开发领域。