C++ STL 学习 :更多仿函数(functor)(二)
时间:2010-07-21 来源:zieckey
C++ STL 学习 :更多仿函数(functor)(二)
C++标准程序库中提供了许多非常有用的预先定义好的的仿函数,了解这些将为我们的开发工作带来便利性和稳健性。
求反值:
// TEMPLATE STRUCT negate |
例如我们对一个vector中所有元素求反:
transform( vect.begin(), vect.end(), vect.begin(), std::negate<int>() ); |
transform参数1:第一个集合的开始(包含)
transform参数2:第一个集合的结束(不包含)
transform参数3:第二个集合的开始(包含)
transform参数4:对第一个集合中的每一个元素应用这个仿函数,仿函数的返回值放到第二个集合中
经过上面解释,那么 transform 算法就是使用 negate 仿函数,将第一个集合中的所有元素求反值之后转移到第二个集合中。这里第二个集合就是自己,那么这段程序就是对“集合中每个元素求反值”
下面看一些更为复杂的仿函数。下面一条语句操作结果是:将容器中所有小于5的元素删除。
std::remove_if( ivec.begin(), ivec.end(), std::bind2nd( std::less<int>(), 5 ) ); |
有点头大了,好长,好多陌生的语法。这里我们一点点解释。
std::less是一个仿函数结构体,不用多说,直接上源码,非常好懂(其实只要理解了operator()就非常好懂这些仿函数)。
// TEMPLATE STRUCT less |
再看std::bind2nd是一个函数,返回一个 std::binder2nd 的仿函数结构体,两个的源码一并放上:
|
bind2nd有两个参数:
第一个参数param1是一个仿函数(这里是std::less),该仿函数必须是带有两个参数的函数。
第二个参数param2一个普通参数,当binder2nd起作用的时候,param2会作为param1这个仿函数的第二个参数(bind2nd,如果是bind1st就是第一个参数)传给param1这个仿函数。
看binder2nd中的operator()重载函数:
result_type operator()(const argument_type& _Left) const { // apply functor to operands return (op(_Left, value)); } |
这里的op就是bind2nd的第一个参数(是一个仿函数,这里是std::less),_Left就是这个仿函数被调用的时候由调用这传入(这里是remove_if),value就是bind2nd的第二个参数(这里是数值 5 )。
OK到这里remove_if中最后一个仿函数参数应该就比较清楚了。
下面说remove_if。说remove_if之前先说find_if。因为remove_if中调用了find_if。
|
从集合_First到_Last中找到第一个符合_Pred条件的值。这里的_Pred是一个仿函数,就是上面提到的std::bind2nd( std::less<int>(), 5 )返回的那个仿函数结构体 std::binder2nd。那么很清楚,就是找到集合中第一个小与5的元素。
找到之后,就最终会调用 _Remove_copy_if,看下面代码:
|
_Remove_copy_if就很简单的一个函数了,就是每找到一个符合要求的元素就将后面所有元素前移动一位,从而实现删除这个元素的操作。
OK。至此remove_if这条语句解释清楚了。
跟remove_if类似的情况还有很多,例如:replace_if 。
看下面一条语句,就是将集合中等于
看整体程序:
|
输出:
initialize : 1, 9, 2, 8, 3, 7, 4, 6, 5, 5, 6, 4, 7, 3, 8, 2, 9, 1, |