在模板库里面,可谓“处处皆模板”,当然了不是模板就不叫模板库了,但是有一点经常让人忽视,使用模板时候,类就真的时候类?也就是说class就真的是类?答案是否定的!
我们看一段代码:
#
include<stdio.h>
typedefintD(intx);

template
<
class
T,
class
R
>
Rgetmy(Rx,T
*
f);

template
<
class
T,
class
R
>
Rgetmy1(Rx,Tf);

Dmy;

intmain(){
printf(
"
x=%d
"
,getmy(
10
,my));
printf(
"
x=%d
"
,getmy1(
10
,my));
return
1
;
}

template
<
class
T,
class
R
>
Rgetmy(Rx,T
*
f){
(
*
f)(x);
return
f(x);
}

template
<
class
T,
class
R
>
Rgetmy1(Rx,Tf){
return
f(x);
}

intmy(intx){
return
x;
}
从上面的getmy函数和getmy1函数就可以看出,里面的class T就不是“类”,仅仅是一个函数,当然了更多情况下我们使用类,这也是很多觉得不要用class标记,而是使用typename标记。
当传入my函数的时候,T类型就自然解释成了D!函数的按地址调用这里就不说了。
回到STL,我们再看标准模板库里面的一个函数:find_if(....)
template
<
class
_InIt,
class
_Pr
>
inline
_InIt_Find_if(_InIt_First,_InIt_Last,_Pr_Pred)
{
//
findfirstsatisfying_Pred
_DEBUG_RANGE(_First,_Last);
_DEBUG_POINTER(_Pred);
for
(;_First
!=
_Last;
++
_First)
if
(_Pred(
*
_First))
break
;
return
(_First);
}

template
<
class
_InIt,
class
_Pr
>
inline
_InItfind_if(_InIt_First,_InIt_Last,_Pr_Pred)
{
//
findfirstsatisfying_Pred
_ASSIGN_FROM_BASE(_First,
_Find_if(_CHECKED_BASE(_First),_CHECKED_BASE(_Last),_Pred));
return
(_First);
}
在find_if的定义里面,第三个参数,被假定为谓词,返回一个bool类型,这里定义是
class _Pr 类型的_Pred变量。
事实上,在stl的设计时候,一般的假定这个变量是一个类对象,可以作为函数对象,或者说拟函数对象,候捷同志(“台湾人我们就称呼为同志吧”)在stl源码剖析一书里面说这个也叫仿函数。
事实不然,他主要接受拟函数对象,但是他肯定是接受常规函数的,只是要保持参数个数、类型以及其返回类型而已。
在《c++程序设计语言》一书的455页就有这么一个函数:
boolless_than_7(intv){
return
v
<
7
;
}

voidf(std::list
<
int
>
&
c){
std::list
<
int
>
::iteratorp
=
find_if(c.begin(),c.end(),less_than_7);
//
……
}
在编译器解释find_if()定义的时候,就把上面的_Pred解释成了一个常规函数,而不是一个类对象。