C++11绑定器bind及function机制( 四 )

this指针对象,所以绑定时绑定器第二个参数传递匿名类对象本身 。bind和之前的bind1stbind2nd一样,最终返回的一定是函数对象,下面的代码将一个五元函数绑定后,返回了一个三元函数对象,效果等同于调用f.operator()(10, 6, 7)
#include <iostream>#include <functional>using namespace std;using namespace placeholders;class Test {public:int func(int a, int b, int c, int d, int e) { return a + b - c + d - e; }};int main() {auto f = bind(&Test::func, Test(), _1, 12, _3, 5, _2);cout << f(10, 6, 7) << endl; //输出:10+12-7+5-6 = 14cout << f.operator()(10, 6, 7) << endl;}作为类成员函数,需要注意的一点是,如果是非静态的成员函数,它会存在一个默认的this指针,静态的成员函数则不存在this指针,所以在将其作为bind函数的参数时,需要注意使用this指针作为其中一个参数,当使用静态成员函数作为参数时,其用法和全局函数类似,当参数为类内非静态成员函数时,第一个参数必须使用&符号 。

注:成为成员函数时,第一个参数之所以必须使用&符号,这部分原因可参考:[ C++中普通函数指针与类成员函数指针的异同 ],文章中有说明具体原因 。
以上就是C++11 bind的使用方法,衍生于bind1stbind2nd,支持更多的参数绑定,关于bind函数更多的使用方法,也可参考C++Boost的说明文档:[ Boost.Bind ] 。关于bind函数绑定的过程,可参考:[ bind原理图释 ],该文章中的图片方便我们对绑定过程的理解 。
C++11 function机制C++11的function机制是C语言中函数指针的衍生,用来实现回调功能,我们上面的绑定器通常都是以语句执行为单位,当出了某个语句的执行后,绑定器返回的这个函数对象也就随之消失,因此需要有回调功能的function去长期保留绑定器返回的函数对象,以便在需要的时候随时通过function机制调用即可 。那有人会问,既然有函数指针,为什么还要再整出来一个function机制?这不是多此一举吗?答案肯定是:很有必要,因为function能做到的,函数指针未必能做到,接下来容我花点篇幅去说明为什么C++中有函数指针还需要std::function
为什么C++中有函数指针还需要std::function?C/C++中可以使用指针指向一段代码,这个指针就叫函数指针,假设有这样一段代码:
#include <stdio.h>int func(int a) { return a + 1; }int main() {int (*f)(int) = func;printf("%p\n", f);return 0;}我们定义了一个函数func,然后使用指针变量f指向该函数,然后打印出变量f指向的地址,代码很简单,然后我们编译一下,看下编译后生成的指令,我们重点关注func函数:
int func(int a) {4005b6: 55push%rbp4005b7: 48 89 e5mov%rsp,%rbp4005ba: 89 7d fcmov%edi,-0x4(%rbp)return a + 1;4005bd: 8b 45 fcmov-0x4(%rbp),%eax4005c0: 83 c0 01add$0x1,%eax}4005c3: 5dpop%rbp4005c4: c3retq可以看到,编译好后的函数func位于地址0x4005b6这个地址,让我们记住这个地址 。然后运行一下编译后生成的程序,想一想这段代码会输出什么呢?显然应该是func函数的在内存中的地址!
[root@localhost 07]# ./a.out0x4005b6没有猜错吧,实际上函数指针本质也是一个指针,只不过这个指针指向的不是内存中的一段数据而是内存中的一段代码,就像这样:
C++11绑定器bind及function机制

文章插图
看到了吧,我们常说的指针一般都是指向内存中的一段数据,而函数指针指向了内存中的一段代码,在这个示例中指向了内存地址

经验总结扩展阅读