为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
慕森卡 2023-04-21 17:13:59
c++自适应二元函数转化为自适应一元函数如图所示,binder1st是个类,那么binder1st (f2,val) f1是什么意思?理解不了啊!
查看完整描述

1 回答

?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

1、首先看一个容器的操作: 

void f(std::vector<int> &vect) 
{
std::vector<int>::iterator firstOne;
for (firstOne = vect.begin();
firstOne != vect.end();
++firstOne)
{
doSomething(*firstOne, "Some string literal");


这个f调用就是完成对容器vect的迭代,并在迭代过程中,处理iter值和一个不变的字符串,至于dosomething完成什么功能,根本不必关心。 
这里有人肯定要说,不是用for_each就可完成这种功能吗,可for_each只接受一个参数的函数。如下所示: 
funcation for_each(iterator beg_it, iterator end_it, funcation func); 
那么怎样让func能够绑定当前iterator值和一个不变的字符串呢?如果成功,问题就OK了。 
在解决这个问题必须要用到适配器函数,如bind1nd, bind2st之流的捆绑函数。在解析这两个函数之前,先看看Funcation的类声明: 
2、Funcation的类声明: 
template <class Arg, class Arg2, class Res> 
struct binary_function {
typedef Arg first_argument_type;
typedef Arg2 second_argument_type;
typedef Res result_type; 
}; 
ok, 我们自己的func也可继承这个基类,哈哈,改进后的dosomething声明: 
class dosomething:public 
std::binary_funcation<int, const char *, void> 

//其中,int是我们当前iterator值类型,const char *是要传递的固定不变的字符串,void是我们func的返回值。看看下面的重载() 声明,就明白了: 
public:
void operator()(int ival, const char *s)
{
// 在这里添加你想干的事情,记住,ival就是当前iterator的值, s是需要绑定的不变字符串

}; 
3、bind1st和bind2nd的选择 
从如上的dosomething可以看出,需要绑定的是s这个不变字符串,是第二个参数,所以当然选择bind2nd,如果dosomething的声明如下: 
class dosomething:public 
std::binary_funcation<const char *, int , void> 

//其中,int是我们当前iterator值类型,const char *是要传递的固定不变的字符串,void是我们func的返回值。看看下面的重载() 声明,就明白了: 
public:
void operator()(const char *s, int)
{
// 在这里添加你想干的事情,记住,ival就是当前iterator的值, s是需要绑定的不变字符串

}; 
那么就当然选择bind1st了,因为需要绑定的不变参数s是第一个参数。 
我靠,原来这两个函数没什么本质区别,只是根据用户定义函数参数的顺序有关。 
4、现在看看改进后的程序: 
#include <vector> 
#include <iostream> 
#include <functional> 
#include <iterator> 
#include <algorithm> 
void doSomething(const char *c, int i); 
// 我的第一个二元功能函数, 
// 首先,我假定doSomething是某个库函数, 
// 我并没有它的源代码。 
// 关于可移植性:MS VC6.0不喜欢在模板的返回类型中使用void, 
// 所以在MS VC6.0中对operator( )稍作修改,使它返回一个类型(如true) 
struct doSomethingWrapper : public 
std::binary_function<const char *, int, void> 
{
// 实际上iValue就是iteraor的derefence值, cValue是不变的捆绑值
void operator()(const char *cValue, int iValue) const
{
doSomething(cValue, iValue);

}; 
// 现在,就建立了一个内部的功能函数。 
// 关于可移植性,同上。 
struct doSomethingDirect : public 
std::binary_function<const char *, int, void> 
{
void operator()(const char *cValue, int iValue) const
{
std::cout << cValue
<< " "
<< iValue
<< ". " << std::endl;

}; 
// 这是个帮助器模板,因为我比较懒,它能减少打字量。 
template <class Collection, class Function> 
Function for_all(Collection &c, const Function &f) 
{
return std::for_each(c.begin(), c.end(), f); 

int main() 

// 首先,建立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; 

// 我独树一帜的第三方库函数 
void doSomething(const char *c, int i) 
{
std::cout << c << " " << i << ". " << std::endl; 

/* 运行结果: 
Wrapper: 1. 
Wrapper: 2. 
Wrapper: 3. 
Wrapper: 4. 
Wrapper: 5. 
Wrapper: 6. 
Wrapper: 7. 
Wrapper: 8. 
Wrapper: 9. 
Direct: 1. 
Direct: 2. 
Direct: 3. 
Direct: 4. 
Direct: 5. 
Direct: 6. 
Direct: 7. 
Direct: 8. 
Direct: 9.


查看完整回答
反对 回复 2023-04-23
  • 1 回答
  • 0 关注
  • 80 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信