在模板库里面,可谓“处处 皆模板”,当然了不是模板就不叫模板库了,但是有一点经常让人忽视,使用模板时候,类就真的时候类?也就是说class就真的是类?答案是否定的!
我们看一段代码:
#
include <stdio.h>
typedef int D(int x);
template < class T, class R >
R getmy(R x, T * f);
template < class T, class R >
R getmy1(R x, T f);
D my;
int main() {
printf( " x = %d " , getmy( 10 , my) );
printf( " x = %d " , getmy1( 10 , my) );
return 1 ;
}
template < class T, class R >
R getmy(R x, T * f) {
( * f)(x);
return f(x);
}
template < class T, class R >
R getmy1(R x, T f) {
return f(x);
}
int my (int x) {
return x;
}
typedef int D(int x);
template < class T, class R >
R getmy(R x, T * f);
template < class T, class R >
R getmy1(R x, T f);
D my;
int main() {
printf( " x = %d " , getmy( 10 , my) );
printf( " x = %d " , getmy1( 10 , my) );
return 1 ;
}
template < class T, class R >
R getmy(R x, T * f) {
( * f)(x);
return f(x);
}
template < class T, class R >
R getmy1(R x, T f) {
return f(x);
}
int my (int x) {
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)
{ // find first satisfying _Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
for (; _First != _Last; ++ _First)
if (_Pred( * _First))
break ;
return (_First);
}
template < class _InIt,
class _Pr > inline
_InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying _Pred
_ASSIGN_FROM_BASE(_First,
_Find_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Pred));
return (_First);
}
class _Pr > inline
_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying _Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
for (; _First != _Last; ++ _First)
if (_Pred( * _First))
break ;
return (_First);
}
template < class _InIt,
class _Pr > inline
_InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying _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页就有这么一个函数:
bool less_than_7 (int v) {
return v < 7 ;
}
void f(std::list < int > & c) {
std::list < int > ::iterator p = find_if(c.begin(), c.end(), less_than_7);
// ……
}
return v < 7 ;
}
void f(std::list < int > & c) {
std::list < int > ::iterator p = find_if(c.begin(), c.end(), less_than_7);
// ……
}
在编译器解释find_if()定义的时候,就把上面的_Pred解释成了一个常规函数,而不是一个类对象。