文章初版来源:
模板类与类模板、函数模板与模板函数等的区别 - wangduo - 博客园
在C++中有好几个这样的术语,但是我们很多时候用的并不正确,几乎是互相替换混淆使用。下面我想彻底辨清几个术语,这样就可以避免很多概念上的混淆和使用上的错误。这几个词是:
- 函数指针——指针函数
- 数组指针——指针数组
- 类模板——模板类
- 函数模板——模板函数
--蓝色的部分指明的是这个术语的本质是什么(即定义的是一个函数/还是一个类/还是一个模板...)
--黑色的部分指明的是这个术语的修饰限定,或者说描述了这个术语它的指向
1.函数指针——指针函数
函数指针的本质是指针。表示的是一个指针,它指向的是一个函数,例子:
int (*pf)(); //定义的是一个指针,是指向整型int的一个指针
指针函数的本质是函数。表示的是一个函数,它的返回值是指针。例子:
int* fun(); //定义的是一个函数(本质),这个函数的返回值是的一个int型指针(限定)
2.数组指针——指针数组
数组指针的本质是指针。表示的是一个指针,它指向的是一个数组,例子:
int (*pa)[8]; //定义的是一个指针,是指向一个整形数组
指针数组的重点是数组。表示的是一个数组,它包含的元素是指针。例子;
int* ap[8]; //定义的是一个数组,数组的元素是一个个的整形指针
3.类模板——模板类(class template——template class)
类模板的重点是模板。表示的是一个模板,专门用于产生类的模子。例子:
1 template <typename T>
2 class Vector
3 {
4 ...
5 };
使用这个Vector模板就可以产生很多的class(类),如
Vector<int>;
Vector<char>;
Vector< Vector<int> >;
Vector<Shape*>;
模板类的本质是类。表示的是由一个模板生成而来的类。例子:
上面的Vector<int>、Vector<char>、……全是模板类。
这两个词很容易混淆,我看到很多文章都将其用错,甚至一些英文文章也是这样。将他们区分开是很重要的,你也就可以理解为什么在定义模板的头文件.h时,模板的成员函数实现也必须写在头文件.h中,而不能像普通的类(class)那样,class的声明(declaration)写在.h文件中,class 的定义(definition)写在.cpp文件中。
4.函数模板——模板函数(function template——template function)
函数模板的重点是模板。表示的是一个模板,专门用来生产函数。例子:
1 template <typename T>
2 void fun(T a)
3 {
4 ...
5 }
在运用的时候,可以显式(explicitly)生产模板函数,fun<int>、fun<double>、fun<Shape*>……。
也可以在使用的过程中由编译器进行模板参数推导,帮你隐式(implicitly)生成。
fun(6);//隐式生成fun<int>
fun(8.9);//隐式生成fun<double>
fun(‘a’);// 隐式生成fun<char>
Shape* ps = new Cirlcle;
fun(ps);//隐式生成fun<Shape*>
模板函数的重点是函数。表示的是由一个模板生成而来的函数。例子:
上面显式(explicitly)或者隐式(implicitly)生成的fun<int>、fun<Shape*>……都是模板函数。
除了这四种自身以外,联合应用来说,类模板(class template)还可以作为模板的模板参数(template template parameter)使用,在Andrei Alexandrescu的《Modern C++ Design》中的基于策略的设计(Policy based Design)中大量的用到。 即一个类的模板作为一个可变类型充当模板的参数,因为一个模板他的类型可变,当然也等同于说明了可变的部分也可以是他自己参数所属的类的类型。
1 template< typename T, template<typename U> class Y>
2 class A
3 {
4 ...
5 };