C++ 函数模板

函数模板是通用的函数描述,它们使用泛型来定义函数,其中的泛型可用具体的类型替换。通过将类型作为参数传递给模板,可使编译器生成该类型的函数。由于模板允许以泛型(而不是具体类型)的方式编写程序,因此有时候也被称为通用编程。

在标准C++98添加关键字typename之前,C++使用关键字class来创建模板。例如:

在C++11中,可以将class替换为typename。

C++ 函数模板_第1张图片

 

调用该函数模板:

 

C++ 函数模板_第2张图片

 

重载的函数模板

例如:

C++ 函数模板_第3张图片

C++ 函数模板_第4张图片

 

模板的显示具体化

假设有一个结构体,C++允许将一个结构体赋给另一个结构体,如果只想交换其中部分成员,则需要不同的代码。

可以提供一个具体化函数定义——显示具体化。当编译器找到与函数调用匹配的具体化时,将使用该定义,而不再寻找模板。

1. 对于给定的函数名,可以有非模板函数,模板函数,和显示具体化函数以及它们的重载版本。

2.显示具体化的原型和定义应以template<>打头,并通过名称来指出类型。

3.具体化优先于常规模板,非模板函数优先于具体化和模板函数。

例如:

C++ 函数模板_第5张图片

C++ 函数模板_第6张图片

 

实例化:

函数调用swap(i,j)导致编译器生成swap()的一个实例,该实例使用int类型。

模板并非函数定义,但使用int的模板实例就是函数定义,这种实例化方式被称为隐式实例化。

C++允许显示实例化,template void swap(int&, int & )

C++ 函数模板_第7张图片

 

编译器选择使用哪个函数版本

对于函数重载,函数模板,函数模板重载,C++有定义一个良好的策略,来决定为函数调用使用哪一个函数定义,尤其是有多个参数时,这个过程称为重载解析。

1.完全匹配,但常规函数优先于模板。

2.提升转换(char 与short自动转换为int,float自动转换为double)。

3.标准转换(int转换为char,long转换为double)。

4.用户定义的转换,如类声明中定义的转换。

 

函数的变量类型与返回类型

函数有多个参数类型时

C++ 函数模板_第8张图片

x + y 的类型无法预测出来,使用decltype关键字来猜测类型。

 

如果函数有返回值类型:无法预先知道x + y的类型,此时还未声明参数x 和 y,他们不在作用域内(编译器无法看到它们,无法使用它们)。必须在声明参数后使用decltype。

C++ 函数模板_第9张图片

现在,decltype在参数后边声明,因此x, y位于作用域内,可以使用它们。

你可能感兴趣的:(C++ 函数模板)