如图所示,binder1st是个类,那么binder1st (f2,val) f1是什么意思?

c++自适应二元函数转化为自适应一元函数如图所示,binder1st是个类,那么binder1st (f2,val) f1是什么意思?理解不了啊!









慕森卡
浏览 120回答 1
1回答

拉莫斯之舞

1、首先看一个容器的操作:&nbsp;void f(std::vector<int> &vect)&nbsp;{std::vector<int>::iterator firstOne;for (firstOne = vect.begin();firstOne != vect.end();++firstOne){doSomething(*firstOne, "Some string literal");}&nbsp;}&nbsp;这个f调用就是完成对容器vect的迭代,并在迭代过程中,处理iter值和一个不变的字符串,至于dosomething完成什么功能,根本不必关心。&nbsp;这里有人肯定要说,不是用for_each就可完成这种功能吗,可for_each只接受一个参数的函数。如下所示:&nbsp;funcation for_each(iterator beg_it, iterator end_it, funcation func);&nbsp;那么怎样让func能够绑定当前iterator值和一个不变的字符串呢?如果成功,问题就OK了。&nbsp;在解决这个问题必须要用到适配器函数,如bind1nd, bind2st之流的捆绑函数。在解析这两个函数之前,先看看Funcation的类声明:&nbsp;2、Funcation的类声明:&nbsp;template <class Arg, class Arg2, class Res>&nbsp;struct binary_function {typedef Arg first_argument_type;typedef Arg2 second_argument_type;typedef Res result_type;&nbsp;};&nbsp;ok, 我们自己的func也可继承这个基类,哈哈,改进后的dosomething声明:&nbsp;class dosomething:public&nbsp;std::binary_funcation<int, const char *, void>&nbsp;{&nbsp;//其中,int是我们当前iterator值类型,const char *是要传递的固定不变的字符串,void是我们func的返回值。看看下面的重载() 声明,就明白了:&nbsp;public:void operator()(int ival, const char *s){// 在这里添加你想干的事情,记住,ival就是当前iterator的值, s是需要绑定的不变字符串}&nbsp;};&nbsp;3、bind1st和bind2nd的选择&nbsp;从如上的dosomething可以看出,需要绑定的是s这个不变字符串,是第二个参数,所以当然选择bind2nd,如果dosomething的声明如下:&nbsp;class dosomething:public&nbsp;std::binary_funcation<const char *, int , void>&nbsp;{&nbsp;//其中,int是我们当前iterator值类型,const char *是要传递的固定不变的字符串,void是我们func的返回值。看看下面的重载() 声明,就明白了:&nbsp;public:void operator()(const char *s, int){// 在这里添加你想干的事情,记住,ival就是当前iterator的值, s是需要绑定的不变字符串}&nbsp;};&nbsp;那么就当然选择bind1st了,因为需要绑定的不变参数s是第一个参数。&nbsp;我靠,原来这两个函数没什么本质区别,只是根据用户定义函数参数的顺序有关。&nbsp;4、现在看看改进后的程序:&nbsp;#include <vector>&nbsp;#include <iostream>&nbsp;#include <functional>&nbsp;#include <iterator>&nbsp;#include <algorithm>&nbsp;void doSomething(const char *c, int i);&nbsp;// 我的第一个二元功能函数,&nbsp;// 首先,我假定doSomething是某个库函数,&nbsp;// 我并没有它的源代码。&nbsp;// 关于可移植性:MS VC6.0不喜欢在模板的返回类型中使用void,&nbsp;// 所以在MS VC6.0中对operator( )稍作修改,使它返回一个类型(如true)&nbsp;struct doSomethingWrapper : public&nbsp;std::binary_function<const char *, int, void>&nbsp;{// 实际上iValue就是iteraor的derefence值, cValue是不变的捆绑值void operator()(const char *cValue, int iValue) const{doSomething(cValue, iValue);}&nbsp;};&nbsp;// 现在,就建立了一个内部的功能函数。&nbsp;// 关于可移植性,同上。&nbsp;struct doSomethingDirect : public&nbsp;std::binary_function<const char *, int, void>&nbsp;{void operator()(const char *cValue, int iValue) const{std::cout << cValue<< " "<< iValue<< ". " << std::endl;}&nbsp;};&nbsp;// 这是个帮助器模板,因为我比较懒,它能减少打字量。&nbsp;template <class Collection, class Function>&nbsp;Function for_all(Collection &c, const Function &f)&nbsp;{return std::for_each(c.begin(), c.end(), f);&nbsp;}&nbsp;int main()&nbsp;{&nbsp;// 首先,建立vector。std::vector<int> vect;for (int i=1; i<10; ++i) {vect.push_back(i);}for_all(vect, std::bind1st(doSomethingWrapper(), "Wrapper:"));std::cout << "/n";for_all(vect, std::bind1st(doSomethingDirect(), "Direct:"));getchar();return 0;&nbsp;}&nbsp;// 我独树一帜的第三方库函数&nbsp;void doSomething(const char *c, int i)&nbsp;{std::cout << c << " " << i << ". " << std::endl;&nbsp;}&nbsp;/* 运行结果:&nbsp;Wrapper: 1.&nbsp;Wrapper: 2.&nbsp;Wrapper: 3.&nbsp;Wrapper: 4.&nbsp;Wrapper: 5.&nbsp;Wrapper: 6.&nbsp;Wrapper: 7.&nbsp;Wrapper: 8.&nbsp;Wrapper: 9.&nbsp;Direct: 1.&nbsp;Direct: 2.&nbsp;Direct: 3.&nbsp;Direct: 4.&nbsp;Direct: 5.&nbsp;Direct: 6.&nbsp;Direct: 7.&nbsp;Direct: 8.&nbsp;Direct: 9.
打开App,查看更多内容
随时随地看视频慕课网APP