Chinaunix首页 | 论坛 | 博客
  • 博客访问: 291415
  • 博文数量: 63
  • 博客积分: 814
  • 博客等级: 军士长
  • 技术积分: 700
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-09 15:46
文章分类

全部博文(63)

文章存档

2017年(1)

2016年(4)

2015年(13)

2014年(9)

2012年(3)

2011年(33)

分类: C/C++

2015-04-09 13:34:26

bind1st bind2nd 的由来

for_each 源码来分析 传入的_Function

template

inline _LIBCPP_INLINE_VISIBILITY

_Function

for_each(_InputIterator __first, _InputIterator __last, _Function __f)

{

    for (; __first != __last; ++__first)

        __f(*__first);

    return _VSTD::move(__f);  // explicitly moved for (emulated) C++03

}


上面__f(*__first); 看得到_Function 只接受一个参数,如果有二个参数情况下怎么办? 于是有了bind1st bind2st 绑定,绑定一个参数,另一个参数就是传入的*iterator .   find_if 等同理。 

所谓 bind1st bind2st 参数绑定,指operator()(...)有二个参数时,指定其中一个绑定,另一个就是*iterator传入;当没有参数或只有一个参数时默认传入的就是*Iterator。所以不需要绑定。
STL 内置函数子类的用法举例

点击(此处)折叠或打开

  1. //移除所有小于100的元素
  2. arr.erase( std::remove_if( arr.begin(), arr.end(),
  3.     std::bind2nd( std::less<int>(), 100)), arr.end());    //(*iterator)val1<100;   operator(..)二个参数


  1. // 移除所有大于100的元素
  2. arr.erase( std::remove_if( arr.begin(), arr.end(),
  3.     std::bind1st( std::less<int>(), 100)), arr.end());   //100operator(..)二个参数

自定义函数子类与函数子类对象举例 effective stl 40 43

点击(此处)折叠或打开

  1. template<typename T>
  2. class Meetsthreshold:public std::unary_function<Widget,bool>{
  3. private:
  4.          const T threshold;
  5. public:
  6.           MeetsThreshold(const T& threshold);
  7.           bool operator()(const Widget&)const;               //一个参数,不需要绑定
  8.         ....
  9. };

  10. struct WidgetNameCompare:
  11.        public std::binary_function<Widget,Widget,bool>{
  12.        bool operator()(const Widget& lhs,const Widget& rhs)const;    //二个参数,需要绑一个
  13. };

针对此函数子的调用

点击(此处)折叠或打开

  1. list<Widget>widgets;
  2. list<Widget>::reverse_iterator i1 = find_if(widgets.rbegin(),widgets.rend(),not1(Meetsthreshold<int>(10)));
  3. //找到最后一个不符合阈值是10 的Widget

  4. Widget w(...);
  5. list<Widget>::iterator i2 =
  6.   find_if(widgets.begin(),widgets.end(),bind2nd(WidgetNameCompare(),w));


bind1st bind2nd 配合 mem_fun 
men_fun_ref 将成员函数生成函数子类对象举例

for_each code 

点击(此处)折叠或打开

  1. class TestClass{
  2.   
  3. public:
  4.     TestClass():data(0)
  5.     {}
  6.     
  7.     void test()
  8.     {
  9.         data++;
  10.     }
  11. private:
  12.     int data;
  13. };

  1.     TestClass *p1 = new TestClass();
  2.     TestClass *p2 = new TestClass();
  3.     TestClass *p3 = new TestClass();
  4.     
  5.     std::vector<TestClass*> lpw;
  6.     lpw.push_back(p1);
  7.     lpw.push_back(p2);
  8.     lpw.push_back(p3);

  9.     for_each(lpw.begin(),lpw.end(),std::mem_fun(&TestClass::test));

           运行后,p1->data = p2->data = p3->data = 1;

find_if code 

点击(此处)折叠或打开

  1.    

    class TestClass1{

        

    public:

        TestClass1(int d):data(d)

        {}

        

        bool test() const

        {

            return data>3;

        }

        

        bool test1(int v) const

        {

            return data>v;

        }

    private:

        int data;

    };




        TestClass1 *t1 = new TestClass1(1);


        TestClass1 *t2 = new TestClass1(2);

        TestClass1 *t3 = new TestClass1(4);

        TestClass1 *t4 = new TestClass1(5);

        

        std::vector lpt;

        lpt.push_back(t1);

        lpt.push_back(t2);

        lpt.push_back(t3);

        lpt.push_back(t4);

        std::vector::iterator it = std::find_if(lpt.begin(),lpt.end(),std::bind2nd(std::mem_fun(&TestClass1::test1),3));        //right


       运行后,p1->data = p2->data = p3->data = 1; 


成员函数有参数的话,与mem_fun men_fun_ref 对接情况下,只能与bind2nd 绑定,因为第一个参数是this本身。 原理参见

http://blog.163.com/ecy_fu/blog/static/4445126200932510531455/

effective stl 40 43中的代码示例,对理解此文有很大帮助,本文引入40中的代码,未引入43中的例子。

现在一切都安静了,因为C++ 11 出来了,这些都可以用方便的lambda 函数来实现了。 参见相关博文。 

阅读(1173) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~