c++函数模板与模板函数

Posted iuk11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++函数模板与模板函数相关的知识,希望对你有一定的参考价值。

函数指针——指针函数

函数指针的重点是指针。表示的是一个指针,指向一个函数。

int (*pf)();

指针函数的重点是函数。表示一个函数,它的返回值是指针。

int* fun();

其实也可以通过运算符优先级来判断,()的优先级比*高。

数组指针——指针数组

数组指针的重点是指针。表示的是一个指针,它指向的是一个数组。

int (*pa)[8];

指针数组的重点是数组。表示的是一个数组,它包含的元素是指针。

int* ap[8];

类模板——模板类(class template——template class)

类模板的重点是模板。表示的是一个模板,专门用来产生类的模子。

template <typename T>
class Vector

;

使用这个Vector模板就可以产生很多的class类,Vector<int>,Vector<char>,Vector<Shape*>,Vector<Vector<int> >...
模板类的重点是类。表示的是由一个模板生成而来的类。
上面的Vector<char>就是模板类。
这两个词很容易混淆,将他们区分开很重要。
所以在定义模板的头文件.h时,模板的成员函数实现也必须写在.h中,不能向普通的类那样,class的声明写在.h中,class的定义写在.cpp中。
关于缺省模板参数的例子:

template <typename T=int>
class Array
;

Array books;编译不会通过,原因是Array不是一个类。
Array <> books;编译成功,<>才是用于缺省模板参数的类模板所生成的一个具体类。

函数模板——模板函数(function template——template function)

函数模板的重点是模板。表示的是一个模板,专门用来生产函数。

template <typename T>
void fun(T a)

在运用的时候,可以显式explicitly生产模板函数,fun<int>,fun<double>,fun<Shape*>...
也可以在使用的过程中由编译器进行模板参数的推到,帮你隐式implicitly生成。
fun(6);//fun<int>
Shape* ps=new Circle;fun(ps);//隐式生成fun<Shape*>
模板函数的重点是函数。表示的是由一个模板生成而来的函数。
上面显式或者隐式生成的fun<int>...都是模板函数。
模板本身的使用是很受限制的,一般来说,他们就只是一个产生类和函数的模子。除此之外,运用的领域就非常少了,所以不可能由什么模板指针存在,即指向模板的指针,这是因为在C++中,模板就是一个代码的代码生产工具,在最终的代码中,根本就没有模板本身存在,只有模板具体出来的具体类和具体函数的代码存在。

模板函数的异常处理

模板函数在模板形参可实例化为各种类型,但当实例化模板形参的各模板实参之间不完全一致时,就可能发生错误。

template<typename T>
void min(T &x,T &y)
	return (x<y)?x:y;

void func(int i,char j)
	min(i,j);

例子中的函数调用是错误的,是因为在调用时,编译器按最先遇到的实参的类型隐含地生成一个模板函数,并且它对所有模板函数进行一致性检查。
min(i,j);先遇到的实参i是整型,编译器就会将模板形参解释为整型,此后出现模板参数j不能解释为整型而产生错误,**模板函数是没有隐含的类型转换功能的。**解决方法有:

  • 采用强制类型转换。
  • 用非模板函数重载函数模板。

方法有两种:
1借用函数模板的函数体
此时只声明非模板函数的原型,它的函数体借用函数模板的函数体。

template<typename T>
void min(T &x,T &y)
	return (x<y)?x:y;

int min(int,int);
void func(int i,char j)
	min(i,j);

此时不会出错了,因为重载函数支持数据间的隐式类型的转换。
2重新定义函数体
就像一般的重载函数一样,重新定义一个完整的非模板函数,它所带的参数可以随意。
C++中,函数模板与同名的非模板函数重载时,应该遵循以下调用原则:

  • 寻找一个参数完全匹配的函数,若找到就调用它。若参数完全匹配的函数多于一个,则这个调用是一个错误的调用。
  • 寻找一个函数模板,若找到就将其实例化生成一个匹配的模板函数并调用它。
  • 若上面两条都失败,则使用函数重载的方法,通过类型转换产生参数匹配,若找到就调用它。
  • 若上面三条都失败,还没有找到都匹配的函数,则这个调用是一个错误的调用。

模板函数与类模板有什么区别

函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。
即函数模板允许隐式调用和显式调用,而类模板只能显式调用。

以上是关于c++函数模板与模板函数的主要内容,如果未能解决你的问题,请参考以下文章

C++入门C++ 函数模板&类模板

[转]C++函数模板与模板函数

C++ 提高教程 模板-普通函数与函数模板调用规则

函数重载与函数模板 - C++

C++模板详解 —— 函数模板与类模板

C++提高编程模板 or 泛型