C++ 函数模板
2017-03-30 10:55
148 查看
一,函数模板
函数模板是通用的函数描述,如果需要将同一种算法用于不同类型的函数,可以使用模板。
函数模板定义
输出结果
二,重载函数模板
可以像重载常规函数定义那样重载函数模板定义,和常规重载一样,被重载的模板的函数特征标必须不同
三,具体化
在代码中包含模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。隐式实例化,显示实例化和显示具体化统称为具体化。
实例:
1, 隐式实例化
函数调用Swap(a, b)导致编译器生成Swap()的一个实例,该实例使用int型。模板并非函数定义,但是使用int的模板实例是函数定义,这种实例化方式成为隐式实例化。编译器之所以知道要进行函数定义,是由于程序调用Swap()函数时提供了int参数。
2,显示实例化
最初编译器只能通过隐式实例化,来生成模板函数的定义,但是现在C++还允许显示实例化,这意味着可以直接命令编译器创建特定的实例。其语法是,声明所需的类型--使用<>符号指示类型,并在声明的前面加上template关键字。如下:template void Swap<int>(int, int)。
3,显示具体化
在程序中定义了上面的结构体,可以使用前面提供的Swap函数来交换两个结构体的内容。然而假如我们只想交换name成员变量,而不交换age成员变量则需要使用不同的代码,但是Swap的参数将保持不变,因此无法使用模板重载来提供其他的代码。可以提供一个具体化函数定义--成为显示具体化,其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。具体化机制随着C++的演变而不断发生变化,下面介绍C++标准定义的形式:
a,对于给定的函数名,可以有非模板函数、模板函数与显示具体化模板函数以及他们的重载的版本。
b,显示具体化的原型和定义应以template<>开头,并通过名称来指定类型。
c,具体化优先与常规模板,而非模板函数优于具体化与常规模板。
四,实例化与具体化的区别
1,实例化
实例化语法,声明所需的类型--用<>符号指示类型,并在声明前面加上关键字template。
template void Swap(int, int);
上面声明的意思是,使用Swap模板生成int类型的函数定义。
2,显示具体化
与上面实例化不同的是,显示具体化使用下面两个等价的声明之一:
template <> void Swap<int>(int, int);
template <> void Swap(int, int);
与上面实例化的区别是,上面这些声明的意思是,不要使用Swap模板来生成函数定义,而是用专门为int类型显示定义的函数定义。这些原型必须有自己的函数定义。显示具体化声明在关键字template后面包含<>,而显示实例化没有。
注意:
试图在同一个文件中使用同一种类型的显示实例和显示具体化将出错。
函数模板是通用的函数描述,如果需要将同一种算法用于不同类型的函数,可以使用模板。
函数模板定义
#include <iostream> using namespace std; template <typename Type> void Swap(Type &a, Type &b){ Type temp = a; a = b; b = temp; } int main(){ int a = 10, b= 20; Swap(a, b); cout<<"a: "<<a<<endl; cout<<"b: "<<b<<endl; return 0; }
输出结果
a: 20 b: 10 Process returned 0 (0x0) execution time : 0.007 s Press any key to continue.
二,重载函数模板
可以像重载常规函数定义那样重载函数模板定义,和常规重载一样,被重载的模板的函数特征标必须不同
template <typename Type> void Swap(Type &a, Type &b){ Type temp = a; a = b; b = temp; } template <typename Type> void Swap(Type *a, Type *b, int n){ Type temp; for(int i = 0; i < n; i ++){ temp = a[i]; a[i] = b[i]; b[i] = temp; } }
三,具体化
在代码中包含模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。隐式实例化,显示实例化和显示具体化统称为具体化。
实例:
template <typename Type> void Swap(Type &a, Type &b){ Type temp = a; a = b; b = temp; }
1, 隐式实例化
函数调用Swap(a, b)导致编译器生成Swap()的一个实例,该实例使用int型。模板并非函数定义,但是使用int的模板实例是函数定义,这种实例化方式成为隐式实例化。编译器之所以知道要进行函数定义,是由于程序调用Swap()函数时提供了int参数。
2,显示实例化
最初编译器只能通过隐式实例化,来生成模板函数的定义,但是现在C++还允许显示实例化,这意味着可以直接命令编译器创建特定的实例。其语法是,声明所需的类型--使用<>符号指示类型,并在声明的前面加上template关键字。如下:template void Swap<int>(int, int)。
3,显示具体化
struct Student{ string name; int age; };
在程序中定义了上面的结构体,可以使用前面提供的Swap函数来交换两个结构体的内容。然而假如我们只想交换name成员变量,而不交换age成员变量则需要使用不同的代码,但是Swap的参数将保持不变,因此无法使用模板重载来提供其他的代码。可以提供一个具体化函数定义--成为显示具体化,其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。具体化机制随着C++的演变而不断发生变化,下面介绍C++标准定义的形式:
a,对于给定的函数名,可以有非模板函数、模板函数与显示具体化模板函数以及他们的重载的版本。
b,显示具体化的原型和定义应以template<>开头,并通过名称来指定类型。
c,具体化优先与常规模板,而非模板函数优于具体化与常规模板。
#include <iostream>输出结果
using namespace std;
struct Student{
string name;
int age;
Student(string name, int age):name(name),age(age){}
};
template <typename Type> void Swap(Type &a, Type &b){ Type temp = a; a = b; b = temp; }
template <> void Swap<Student>(Student &a, Student &b){
string name = a.name;
a.name = b.name;
b.name = name;
}
int main(){
Student a("zhangsan", 20);
Student b("lisi", 25);
Swap(a, b);
cout<<"a.name: "<<a.name<<endl;
cout<<"b.name: "<<b.name<<endl;
return 0;
}
a.name: lisi b.name: zhangsan Process returned 0 (0x0) execution time : 0.007 s Press any key to continue.
四,实例化与具体化的区别
1,实例化
实例化语法,声明所需的类型--用<>符号指示类型,并在声明前面加上关键字template。
template void Swap(int, int);
上面声明的意思是,使用Swap模板生成int类型的函数定义。
2,显示具体化
与上面实例化不同的是,显示具体化使用下面两个等价的声明之一:
template <> void Swap<int>(int, int);
template <> void Swap(int, int);
与上面实例化的区别是,上面这些声明的意思是,不要使用Swap模板来生成函数定义,而是用专门为int类型显示定义的函数定义。这些原型必须有自己的函数定义。显示具体化声明在关键字template后面包含<>,而显示实例化没有。
注意:
试图在同一个文件中使用同一种类型的显示实例和显示具体化将出错。
相关文章推荐
- c++入门学习(函数模板)
- 王老师 C++ 函数重载和模板 第二讲
- C++箴言:用成员函数模板接受兼容类型
- C++中 函数,函数模板,函数对象,函数对象模板 与 回调机制 不得不说的事
- 利用C++模板,代替虚函数,实现类的静态多态性(加入性能测试部分)
- C++中的函数模板
- C/C++ 函数模板
- C++模板之函数模板
- 【转】王老师 C++ 函数重载和模板
- [C++再学习系列] 函数模板和类模板
- 未解决-深入C++之函数模板
- C++模板的定制一:定制函数模板
- C++模板的定制五:对定制成员函数的补充
- C++ 函数模板和类模板(转)
- C++模板:函数模板和模板函数
- 王老师 C++ 函数重载和模板 第一讲
- 利用C++模板,代替虚函数,实现类的静态多态性(加入性能测试部分)
- 利用C++模板,代替虚函数,实现类的静态多态性(加入性能测试部分)
- c++学习---函数模板
- C++ 函数模板 二义性 问题