函数模板是C++中一种通用编程技术,允许编写可以适用于多种数据类型的函数,而无需为每种数据类型编写不同的函数。函数模板通过参数化类型来实现通用性,可以在不同情况下自动生成具体的函数代码。
目录
1.函数模板的定义
2.函数模板的使用
3.函数模板与普通函数
4.函数模板的局限性
1.函数模板的定义
函数模板以 template
关键字开始,后面跟着尖括号(<>),其中包含一个或多个类型参数。
template <typename T>
T myMax(T a, T b) {return (a > b) ? a : b;
}
如果我需要再对两个float类型的变量进⾏交换,是不是还需要再写⼀个函数呢?需要交换的变量的类型越多,我就越需要写更多的重复的函数,而且⼀旦需求变更了,交换的逻辑需要做⼀些小小的改变。那么每⼀个函数我都得修改⼀下,非常的复杂
我如果能够设计⼀个通用的函数,能够把类型当作参数传递到这个函数中,就可以简化很多很多的⼯作了!这就是函数模板!
// 需求:我想要设计⼀个函数,实现两个int变量的值的交换
void mySwap(int& a, int& b) {int tmp = a;a = b;b = tmp;
}
// 需求:我想要设计⼀个函数,实现两个double变量的值的交换
void mySwap(double& a, double& b) {double tmp = a;a = b;b = tmp;
}
template<typename T>
void mySwap(T& a, T& b) {T tmp = a;a = b;b = tmp;
}
2.函数模板的使用
template<class T>
void mySwap(T& a, T& b) {T tmp = a;a = b;b = tmp;
}
int main() {int a = 10, b = 20;double x = 3.14, y = 0.99;// 1. 显式指定类型mySwap<int>(a, b);// 2. 可以⾃动根据实参的类型进⾏推导mySwap(a, b); // 这⾥调⽤的mySwap中,类型T被推导为int类型mySwap(x, y); // 这⾥调⽤的mySwap中,类型T被推导为double类型// 注意事项: 类型推导的时候,需要保证⼀致性。不满⾜⼀致性⽆法推导。// 例如 mySwap(a, y); // 第⼀个实参a是int类型,推导T的类型为int;第⼆个实参y是double类型,推导T的类型为double;
不⼀致return 0;
}
3.函数模板与普通函数
在以下示例中,add
函数模板可以处理 int
和 double
类型的参数,而普通函数 add
仅能处理 int
类型参数。函数模板实现了更广泛的通用性和类型安全性。
// 函数模板
template <typename T>
T add(T a, T b) {return a + b;
}// 普通函数
int add(int a, int b) {return a + b;
}int main() {int x = 5, y = 10;double p = 3.14, q = 2.71;int result1 = add(x, y); // 调用普通函数double result2 = add(p, q); // 调用函数模板return 0;
}
4.函数模板的局限性
函数模板虽然很通用,但并不是万能的,有的时候也会出现不适配的情况。
template<class T>
bool compare(const T& t1, const T& t2) {return t1 > t2;
}
对于上述的模板函数来说,如果是比较整形、浮点型甚至字符型的数据是没有问题的。可是如果我们设置为person类呢?两个person对象无法进行大小比较,这里也就自然的出现了问题。
那么如何解决这样的问题呢?
1. 重载运算符,重载>运算符。
2. 通过函数模板的重载来解决。
函数模板的重载,就是为了解决特定类型的对象的问题,通过函数模板的重载,可以为这些特定的数据类型提供具像化的模板。
class Person {
public:int age;
};
template<class T>
bool compare(const T& t1, const T& t2) {return t1 > t2;
}
template<>
bool compare<Person>(const Person& p1, const Person& p2) {return p1.age > p2.age;
}
int main() {Person p1;p1.age = 15;Person p2;p2.age = 12;cout << compare(p1, p2) << endl;return 0;
}
由于我们在特化的 compare
函数中定义了如何比较两个 Person
对象的年龄属性,因此在 main
函数中调用 compare(p1, p2)
时,实际上是调用了特化版本的 compare
函数,返回的结果是根据年龄比较的结果。