FunctionObjectType fo;
...
fo(...);
其中表达式fo()是调用仿函数fo的operator()。你可以将仿函数看成一般的函数。仿函数有三大好处:
1。仿函数拥有自己的状态。你可以同时拥有多个状态不同的实体。
2。仿函数可以写为class template,从而指定某种行为模式。
3。执行速度上,仿函数通常比函数指针更快。
所谓“函数配接器”function adaptor,是指能够将仿函数和另外一个仿函数或函数结合起来的仿函数。
例如:
find_if(coll.begin(),coll.begin(), bind2nd(greater<int>(),42));
其中的表达式 bind2(greater<int>(),42)就是一个组合型仿函数,检查某个int值是否大于42。实际上bind2nd是将一个二元仿函数转化为一元仿函数。
------------------------------------------------------------------------------
一 iterator
stl中算法通过iterator作用于数据的线性区间(linear range).
iterator是类似于指针的东东.它有几种不同的类型(不是C++语言中的类型,是一种concept(约定)),分别提供各种层次的功能,以满足不同算法的需要.
比如:
input iterator
支持:
== * ++
不支持:
= -- > <
mutlipass(多次历遍)
同时拥有两个input iterator(不知道术语是什么,望大侠赐教)
等等,可以参见<泛形编程与STL>.
iterator_traits是用来定义iterator的指向物的数据类型的(听说0x标准会增加typeof,有了typeof是不是可以简化一下???who can tell me?).
iterator_traits中还有一项iterator_category,是一个空类的typedef,用来标识iterator的类型(如input iterator).
可以配合函数的重载,针对不同类型的iterator,写其最有效率的算法.
二 函数对象(function object)
"羊吃草"可以理解"将羊这个函数对象 通过吃这种算法 作用于草这个区间".
function object相当于羊,通过替换function object为牛,马,我们可以实现不同的目的(比如羊吃草是为了产毛,牛吃草是为了耕地,马吃草为了赶路).
function object中有一类叫做adaptable function object,它们作用类似iterator_traits,不过没有单独写成一个object.他们通过了自身参数和返回值的typedef.
可以用于function object adapter中,比如一个作用类似于"!"(not)的function object adapter.
stl中通过adaptable function object的基类,以方便使用.
刚看到这里,下次继续...................
-----------------------------------------------
1.Function object Adaptor?
Adaptors are template classes that provide interface mappings.
基于其他类来实现新的功能,成员函数可以被添加、隐藏,也可合并以得到新的功能。
STL中的算法和容器一般都需要函数对象(function object)作为参数。如果想用到常用的C++函数时,可以用ptr_fun把普通函数转换成函数对象。比如ptr_fun(strcmp)就把常用的串比较函数strcmp包装成一个函数对象,就可用在STL算法和容器中了。
--------------------------------------------------------
2.bind1st和bind2nd?
作用:简称为bind函数,可以将一些值限定在指定区间中。取得一个object中的value作为上限和下限。
比较的时候所写的表达式像 x > k ,x < k,这里的k是一个参数表示你程序里面的表达式要和k值去比较。上面这两个表达式对应的应该是bind2nd ,简单的理解就是把k作为比较表达式的第二个参数。如果使用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。
例如:
int a[] = {1, 2, 100, 200};
std::vector< int> arr(a, a + 4);
// 移除所有小于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::less< int>(), 100)), arr.end());
这里的比较表达式相当于arr. < 100
如果用bind1st则表达的意思就恰恰相反
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind1st( std::less< int>(), 100)), arr.end());
这里的表达式相当于100 < arr.
当然为了实现删除大于100的元素你同样可以使用bind2nd
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::greater< int>(), 100)), arr.end());
---Sava
---------------------------------------------------------------
bind1st和bind2nd函数用于将一个二元算子(binary functor,bf)转换成一元算子(unary functor,uf)。为了达到这个目的,它们需要两个参数:要转换的bf和一个值(v)。
可能这么解释以后大家还不是很清楚,那么就说点白话吧。我们在做比较的时候所写的表达式像 x > k ,x < k,这里的k是一个参数表示你程序里面的表达式要和k值去比较。上面这两个表达式对应的应该是bind2nd ,简单的理解就是把k作为比较表达式的第二个参数。如果使用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。大家可能会注意到这里面没有=的比较,先别着急,后面将会说道如何实现=的比较。先举两个例子看看bind1st和bind2nd的用法。
int a[] = {1, 2, 100, 200};
std::vector< int> arr(a, a + 4);
// 移除所有小于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::less< int>(), 100)), arr.end());
这里的比较表达式相当于arr. < 100
如果用bind1st则表达的意思就恰恰相反
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind1st( std::less< int>(), 100)), arr.end());
这里的表达式相当于100 < arr.
当然为了实现删除大于100的元素你同样可以使用bind2nd
// 移除所有大于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::bind2nd( std::greater< int>(), 100)), arr.end());
前面说道=的比较,比如说x <= k怎么实现呢,std又提供了一个好东西not1,我们可以说 !(x > k) 和 x <= k是等价的,那么我们看看下面的表达式:
// 移除所有小于等于100的元素
arr.erase( std::remove_if( arr.begin(), arr.end(),
std::not1(std::bind2nd( std::greater< int>(), 100))), arr.end());
说明:not1是否定返回值是单目的函数,std中还有not2它是否定返回值是双目的函数