函数模板
Why function templates
The definitions of some overloaded functions may be similar.
函数重载的定义可能相似。
int sum(int x, int y)
{
cout << "sum(int, int) is called" << endl;
return x + y;
}
float sum(float x, float y)
{
cout << "sum(float, float) is called" << endl;
return x + y;
}
double sum(double x, double y)
{
cout << "sum(double, double) is called" << endl;
return x + y;
}
三个函数的功能相同,计算逻辑相同,只是类型不同。这三个函数功能非常简单,无非就是两数相加,但是如果函数功能非常复杂,也仅仅是函数返回类型不同,这三个函数就会有非常多重复的地方,代码不美观又冗余,维护困难,怎么办?
Explicit instantiation
- A function template is not a
type
, or a function, or any otherentity
. - No code is generated from a source file that contains only template definitions.
- The template arguments must be determined, then the compiler can generate an actual function
```cpp
include
include
using namespace std;
template
// instantiates sum
// instantiates sum
int main() { auto val = sum(4.1, 5.2); cout << val << endl;
auto val_1 = sum(4, 5);
cout << val_1 << endl;
auto val_2 = sum('2', '1');
cout << val_2 << endl;
return 0;
}
// The input type is d // 9.3 // The input type is i // 9 // The input type is c // c
`T`是泛型,通用数据类型,可以代表各种数据类型。`typeid(T).name() `:输入参数的类型。<br />这就是一个函数模板,编译器编译的时候,遇到函数模板,并不会生成可执行代码,因为编译器不知道加法(整数加法与浮点数加法是不同的)怎么执行。
如果想让编译器编译它,需要再**实例化**这个模板函数,告诉编译器`T`是`double`类型,然后编译器就会生成三个不同的函数,其在机器指令中是不同的代码,调用它们的机器码的地址也是不同的。
函数模板是虚拟的,编译器把握不住,所以编译器一定要要求生成一个实实在在的函数,所以函数模板需要实例化,才能生成真正的函数。
尝试:<br />将第一个实例化的`double`类型改成`float`,运行结果:`The input type is d`;将其注释掉,仍然可以编译通过,运行结果仍然是:`The input type is d`;<br />WHY????
函数模板可以做显式的实例化,也可以做隐式的实例化!
**Implicit instantiation**<br />Implicit instantiation occurs when a function template is not `explicitly instantiated`.<br />编译器在编译的时候,遇到函数模板,但不知道如何实现该模板函数,就会去找显式的声明,显式实例化找不到,就会去找函数调用,就会隐式的实例化该模板函数,生成函数实现的机器码
```cpp
#include <iostream>
#include <typeinfo>
using namespace std;
template<typename T>
T sum(T x, T y)
{
cout << "The input type is " << typeid(T).name() << endl;
return x + y;
}
int main()
{
// Implicitly instantiates product<int>(int, int)
cout << "sum = " << sum<int>(2.2f, 3.0f) << endl;
// Implicitly instantiates product<float>(float, float)
cout << "sum = " << sum(2.2f, 3.0f) << endl;
return 0;
}
// sum = The input type is i
// 5
// sum = The input type is f
// 5.2
Function template specialization
We have a function template: template<typename T> T sum(T x, T y)
- If the input
type
isPoint
But nostruct Point { int x; int y; };
+
operator forPoint
We need to give a special definition for this case. ```cppinclude
include
using namespace std;
template
struct Point { int x; int y; };
// Specialization for Point + Point operation
template<> // <> 特例化
Point sum
int main() { //Explicit instantiated functions cout << “sum = “ << sum(1, 2) << endl; cout << “sum = “ << sum(1.1, 2.2) << endl;
Point pt1 {1, 2};
Point pt2 {2, 3};
Point pt = sum(pt1, pt2);
cout << "pt = (" << pt.x << ", " << pt.y << ")" << endl;
return 0;
} ```