在讲函数模板之前就要先讲讲函数重载了
#include using namespace std; int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } int main() { cout << add(2, 3) << endl; cout << add(2.5, 3.7) << endl; return 0; } 在上面代码我们可以知道除了内置类型不同其他的功能都是一样的,那既然重要功能都一样那我们能不能让它们合二为一,这样就可以处理多种数据类型的情况了,在C++中就可以使用函数模板来解决此类问题
函数模板允许我们编写与类型无关的函数。这样我们就可以在一次编写中处理不同的数据类型,而不必重复编写相同的代码。函数模板使用template关键字定义。
代码示例:
#include using namespace std; template //也可以 T add(T a , T b) { return a + b; } int main() { cout << add(2, 3) << endl; cout << add(2.5, 3.7) << endl; return 0; } 这时我们是不是心里面有个疑问,为什么T知道我是什么数据类型,那下面请跟我详细分析
当编译器遇到模板函数的定义时编译器只记录模板的定义,并不会立即生成代码。编译器遇到函数调用add(2, 3):它推断参数2和3是int类型,所以推断模板参数T为int。用int替换T,生成具体函数int add(int a, int b)。在这过程中虽然我们通过代码看到的依然时T但是内部已经全部换成了int类型了,所以说到底还是编译器承受的太多了。
还有一个疑惑就是我又调用了一个double那不是有两个类型了但是上面接收函数只有一个,编译器不会搞混吗?
编译器在编译过程中会生成两个具体的函数,一个用于int类型,一个用于double类型:
例
int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } 因此,编译器会生成两个不同的函数实例,不会有混淆。
通过模板,我们可以编写更简洁、复用性更高的代码,而编译器会根据具体使用的类型生成对应的函数,不会混淆不同的类型。
隐式实例化是指编译器根据实参推断模板参数的类型,然后实例化模板函数。
代码示例:
template T Add(const T& left, const T& right) { return left + right; } int main() { int a1 = 10, a2 = 20; double d1 = 10.0, d2 = 20.0; Add(a1, a2); // T 被推断为 int,实例化为 int Add(const int&, const int&) Add(d1, d2); return 0; } 显式实例化是指在调用模板函数时明确指定模板参数的类型。
代码示例:
#include using namespace std; template //也可以 T add(T a , T b) { return a + b; } int main() { cout << add(2, 3) << endl; cout << add(2.5, 3.7) << endl; return 0; } 当函数模板跟非函数模板在一起时,那咋们该怎么样调用呢?
代码示例:
#include using namespace std; // 专门处理 int 类型的加法函数 int Add(int left, int right) { return left + right; } // 处理 double 类型的加法函数 double Add(double left, double right) { return left + right; } // 通用加法函数模板 template auto Add(T1 left, T2 right) -> decltype(left + right) { return left + right; } void Test() { cout << Add(1, 2) << endl; // 调用非模板函数 Add(int, int) cout << Add(2.5, 3.5) << endl; // 调用非模板函数 Add(double, double) cout << Add(1, 2.0) << endl; // 调用模板函数 Add(int, double) } int main() { Test(); return 0; } 类模板是C++中的一种机制,用于创建通用类,允许类的成员使用不特定的数据类型。类模板可以使代码更加通用和可重用,避免为每种数据类型编写重复的代码。
template class Box { public: Box(T value) : _value(value) {} private: T _value; }; int main() { Box intBox(123); // 实例化 Box,T 为 int Box doubleBox(45.67); } 那在类模板中可不可以隐式实例化呢?
对于类模板,编译器不能自动推断模板参数的类型,必须显式指定。而对于函数模板,编译器确实可以根据传递的参数自动推断模板参数的类型。
对于类模板我们先讲这些到后面咋们慢慢补上