深入C++之函数模板

转载 2004年08月21日 10:28:00
深入C++之函数模板

[原创] zengyi820 2003-07-01
第十章 函数模板
Chapter 10 Function template

本章要点概述:
1.什么是模板(what a function template is)
2.定义和使用模板(how to define and use a function template)
3.函数模板的推演过程(template argument deduction)
4.引用模板实例时如何指定显示模板参数(how explicit template arguments can be specified when referring to a function template instantiation)
5.编译器模板的初始化以及对程序组织的要求(how the compiler instantiates templates and the requirements this imposes on the organization of our programs)
6.定义函数模板实例的特化版本(how to define a specialization for a function template instantiation)
7.函数模板的重载及其解析过程如何工作(how function templates can be overloaded and how overload resolution involving function templates works)
8.函数模板定义中的名字解析(name resolution in function template definitions)
9.函数模板定义在名字空间中的方式(how function templates can be defined in namespaces)
10.1函数模板的定义(Function Template Definition)
(1)由强类型语言需求引出的问题:
强类型语言需要我们对不同的类型参数定义不同类型的函数
int min( int a, int b )
{
?? return a < b ? a : b;
}

double min( double a, double b ) {
return a < b ? a : b;
}
??
我们尝试用预处理器的宏扩展设施解决这个问题
#define min(a,b) ((a) < (b) ? (a) : (b))

这样的工作机制存在问题:我们来解析一下,预处理器的宏扩展设施的工作机制不是对函数的调用,而是简单的提供参数的替换,两个参数值被计算了两次,一次是比较a,b。一次是宏的返回值计算。
??使用函数模板保留了函数定义和函数调用的语义(函数调用之前实参只被计算一次),其核心算法的功能是:程序员可以对函数接口的全部或者部分类型进行参数化,而函数体保持不变。
(2)函数模板的构造准则(The Principle of Function Template Creation)
函数的实现在一组实例上保持不变,每个实例都处理一种唯一的数据类型,这样的函数就可以构造成函数模板
template
Type min( Type a, Type b ) {
return a < b ? a : b;
}
int main() {
// ok: int min( int, int );
min( 10, 20 );
// ok: double min( double, double );
min( 10.0, 20.0 );
return 0;
}

(3)函数模板的定义(Function Template Definition)
template总是放在模板定义与声明的最前面
<>中的是模板参数表,不可为空,模板参数有两类:
模板类型参数(template type parameter list):由关键字class或typename(在函数模板的参数表中两者意义相同)后加一个标识符构成。标识符(如上面的Type)可以是任何名字。
模板实例化时,实际的内置或用户定义类型将替换模板的类型参数。模板类型参数用来声明变量和强制类型转换。有效的模板实参类型:int、double、char*、vector或list*
模板非类型参数(template nontype parameter):由一个普通的参数声明构成,代表了一个潜在的值,该值是模板定义中的一个常量
template
Type min( Type (&arr) [size] );
Size就是该函数模板的非类型参数,代表arr指向的数祖的长度,函数min()实例化时,size将被编译时已知的常量值替代。模板非类型参数常用在数组声明中指定数组的大小或者是作为枚举常量的初始值
调用函数和取函数地址是函数的两种使用方法
(4)函数模板定义中应注意的若干问题
a.如果在全局域中声明了与模板参数同名的对象、函数或类型,则该全局名将被隐藏,如下程序段:
typedef double Type;
template
Type min( Type a, Type b )
{
Type tmp = a < b ? a : b; // tmp 类型为模板参数 Type,而不是全局的typedef
return tmp;
}

b.在函数模板定义中声明的对象或类型不能与模板参数同名
template
Type min( Type a, Type b ){
typedef double Type; // 这里就重新声明了模板参数,所以是个错误
Type tmp = a < b ? a : b;
return tmp;
}

c.模板类型参数名可以被用来指定函数模板的返回值
template
T1 min( T2, T3 );

T1指明了函数min()返回值的类型,T2和T3指明的是参数的类型
d.模板参数名在同一模板中不可重名,但是在不同的函数模板声明中就可以重复的使用。
e.每个模板类型参数都必须有关键字typename或者class在前面,两者可以互换。
f.模板函数被声明为inline或extern的格式:指示符要放在参数表的后面
正确:
template
inline
Type min( Type, Type );

错误:
inline
template
Type min( Array, int );
下面我们来看经典教材C++ Primer当中的两个练习以加深巩固.
指出下列函数模板的定义哪些是错误的,哪些是这确的,并将其改正
(a) template
void foo( T, U, V );

模板的定义应该为template ,依据:每个模板类型参数都必须有关键字typename或者class在前面,两者可以互换。
(b) template
T foo( int *T );

正确
(c) template
T1 foo( T2, T3 );

正确
(d) inline template
T foo( T, unsigned int* );

应该为:
template
inline
T foo( T, unsigned int* );

指示符:模板函数被声明为inline或extern的格式时指示符要放在参数表的后面
(e) template
void foo( myT, myT );

模板参数名在同一模板中不可重名。
可以改为:
template
void foo( myT, myT );
(f) template
foo( T, T );

正确
(g) typedef char Ctype;
template
Ctype foo( Ctype a, Ctype b );

正确
练习10.2 下列模板重复声明中哪些是错误的,为什么
(a) template
Type bar( Type, Type );
template
Type bar( Type, Type );
(b) template
void bar( T1, T2 );
template
void bar( C1, C2 );

两个都是正确的

C++模板深入理解

如何组织编写模板程序 前言 常遇到询问使用模板到底是否容易的问题,我的回答是:“模板的使用是容易的,但组织编写却不容易”。看看我们几乎每天都能遇到的模板类吧,如STL, ATL, WTL, 以及Bo...
  • fenxinzi557
  • fenxinzi557
  • 2016-08-12 12:01:32
  • 794

深入理解C++template的基础知识

1.参数化的声明  C++现今支持两种基本类型的模板:类模板和函数模板(也包括成员模板), 这些模板的声明与普通类与普通函数的声明很相似,唯一的区别就是模板声明需要引入一个参数化的子句,子句的格式大体...
  • Echoes_smile
  • Echoes_smile
  • 2017-09-02 13:53:09
  • 320

《深入实践C++模板编程》笔记

2014-07-31 《深入实践C++模板编程》 @ALL 作者: Claude Mar 24 像这样的书, 估计也只需要这一个笔记就可以了。 太坑爹了, 根本没有深入好不好。  但是, 从另外一...
  • cloudqiu
  • cloudqiu
  • 2017-02-10 11:58:29
  • 942

程序猿学习资料集

编程学习中经常要访问一些网站找资料,为了以后便于查找,在这里做下整理。    哎,越学越觉得自己还只是个菜鸟!励志成为一个小小的全栈工程狮。    我的Github地址:https://githu...
  • u012562943
  • u012562943
  • 2016-07-17 10:03:40
  • 4588

多年收集的VC++电子书,源代码现在免费全部奉献给大家

多年收集的VC++电子书,源代码现在免费全部奉献给大家 这里只列举了一点书籍和代码,我已经将电脑中全部资料上传到网址里面 !!!!!!!!!!!!全部免费!!!!!!!!!!!!!!!!!! 规...
  • e_wsq
  • e_wsq
  • 2013-05-06 22:41:12
  • 3079

C++实践参考:排序函数模板

【项目-排序函数模板】   已知void Sort(int a[],int size); void Sort(double a[],int size);是一个函数模板的两个实例,其功能是将数组a中的...
  • sxhelijian
  • sxhelijian
  • 2016-05-26 15:16:03
  • 2191

C++函数模板的使用

函数模板: 函数模板是函数的蓝图或处方,编译器使用它生成函数系列的新成员。新函数在第一次使用时创建。从函数模板中生成的函数称为该模板的一个实例或模板的实例化。函数模板的开头是关键字template,表...
  • u010142437
  • u010142437
  • 2014-06-17 15:40:32
  • 1512

一些大牛的博客

天看到一篇文章,收藏了很多大牛的博客,在这里分享一下(转载于:http://blog.csdn.net/wellto/article/details/12838675) Android中文Wiki ...
  • o190847959
  • o190847959
  • 2015-06-19 10:58:49
  • 8503

c++电子书籍下载

数据结构与算法(Java语言描述).pdf: http://www.t00y.com/file/9972024 数据结构与算法-面向对象的C++设计模式-shrinked.PDF: http://w...
  • Cloud_Strife_1985
  • Cloud_Strife_1985
  • 2012-12-03 14:19:22
  • 4930

C++模板:函数模板和模板函数

1.函数模板的声明和模板函数的生成 1.1函数模板的声明 函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计。它的最大特点是把函数使用的数据类型作为参数。 ...
  • BeyondHaven
  • BeyondHaven
  • 2009-05-20 17:08:00
  • 123977
收藏助手
不良信息举报
您举报文章:深入C++之函数模板
举报原因:
原因补充:

(最多只允许输入30个字)