STL笔记:函数配接器(Function adapters)

一:STL预定义函数配接器的使用

STL预定义的函数配接器
1. bind1st(op, value)
2. bind2st(op, value)
3. not1(param)
4. not2(param1,param2)

函数配接器可以将仿函数和另一个仿函数结合起来。
函数配接器本身也是仿函数。

二元函数配接器示例:
find_if( coll.begin(), coll.end(), bind2nd(greater<int>(),42) );
以上例句中,bind2nd将仿函数greater<int>()和第二个参数整型数42结合起来,查找条件就变成了“大于42”。
其中greater<int>为STL预定义的仿函数,接收两个参数比较,第一个参数为coll中元素,第二个参数42作为greater<int>的内部参数保存,上面的语句相当于以下伪代码的逻辑(注意只是相等逻辑,非STL实现):

greater<int>    functorGreater;     //在find_if语句内部,仿函数会创建一个实例对象
for(std::vector<int>::const_iterator It = coll.begin();    It != coll.end(); ++It )
{
    if( functorGreater(*It,42) )     //调用仿函数greater<int>内部的重载操作符"()"完成比较操作
    return It;

    return coll.end();
}

 

类似的,一元函数配接器:

find_if( coll.begin(),    coll.end(),    bind1nd(greater<int>(),42)    );

只是想当把以上伪代码中的

if( functorGreater(*It,42) )
改成
if( functorGreater(42,*It) )
可见,仿函数命名bind1st,bind2nd意思是指定第几个元素是要作为“被绑定的仿函数”的内部参数的。


not1()将结果取反:

find_if( coll.begin(),    coll.end(),    not1(bind2nd(greater<int>(),42))    );

返回小于等于42的值。

not1()与not2()区别只是后者用于接收两个形参的表达式: not2(op) //这里的op接收两个形参,not2将op的返回值取反

 

二:针对成员函数的函数配接器
成员函数的函数配接器(注意op均为const),同普通函数配接器,只是被配接的函数是类的成员函数。
1.mem_fun_ref(op)
2.mem_fun(op)

示例(Win7 64 + Visual studio 2010):

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <iterator>

using namespace::std;

class TestClass
{
public:
    TestClass(int i):index(i){}

void print() const
{
    cout<<"TestClass"<<index<<endl;;
}

int operator()()
{
    return index++;
}

private:
    int index;
};

int main()
{
    vector<TestClass> testVector;

    generate_n(back_inserter(testVector),10,TestClass(1));
    for_each(testVector.begin(),testVector.end(),             mem_fun_ref(&TestClass::print));    //遍历输出

    return 0;
}

 

以上代码中,mem_fun_ref调用了TestClass中的print成员函数,而且print函数必须为const。
mem_fun和mem_fun_ref区别在于,后者调用的是类引用类型,前者是指针类型:
若testVector类型为vector<TestClass*>
则需要调用mem_fun(&TestClass::print)

 

三:一般函数的函数配接器
参考成员函数的配接器,基本没啥不同。
如有全局函数

void printTestClass(TestClass& refTC)
{
    refTC.print();
}

调用:

for_each(testVector.begin(),testVector.end(), ptr_fun( printTestClass ) );

 

四:自定义仿函数的函数配接器
自定义仿函数需要提供类型成员来指定参数和返回值类型,可继承以下STL中定义的模板来确定规范化:

template<class Arg,class Result>
struct unary_function
{
typedef Arg argument_type;
typedef Result result_type;
}

template<class Arg1,class Arg2,class Result>
struct binary_function
{
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
}

 

 

posted @ 2013-08-08 00:03  inary  阅读(401)  评论(0编辑  收藏  举报