前期准备
- C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include
- Copyright (c) by P.J. Plauger. All rights reserved.
- Consult your license regarding permissions and restrictions.
V6.50:0009
bind
我们先来研究一下bind,这个bind实际上用途极为广泛,特别是在多线程的程序中,经常用它将函数进行包装,然后打包发送给工作线程,让工作线程去执行我们的任务。
代码范例
#include "stdafx.h"
#include <functional>
using namespace std;
int myfunc(int a, int b, int c )
{
int d = a + b + c;
return d;
}
int firstfunc(int a)
{
int b = a;
return b;
}
int main()
{
auto myfunctemp = bind(myfunc, 1,2,3);
auto myfunctemp2 = bind(firstfunc, 4 );
myfunctemp();
myfunctemp2();
return 0;
}
上面是个函数使用的范例,我们来看一下,模板背后的汇编故事,下面这个是第一个函数myfunc的生成实例。
ConsoleApplication1.exe!
std::bind<int (__cdecl&)(int,int,int),int,int,int>
(
int(*)(int, int, int) _Func,
int && <_Args_0>,
int && <_Args_1>,
int && <_Args_2>
) 行 894 C++
函数头对应的汇编位置为011854C0
接着是第二个函数firstfunc的生成实例
ConsoleApplication1.exe!
std::bind<int (__cdecl&)(int),int>
(int(*)(int) _Func,
int && <_Args_0>
) 行 893
函数头对应的汇编位置为01185460
由此我们发现,根据同一模板,输入不同的特例生成不同的函数,执行不同的实例。
这是我们一种最为简单的bind的使用方法,然后接着我们详细分析一下其后面的逻辑过程。
bind函数
// TEMPLATE FUNCTION bind (implicit return type)
template<class _Fx,
class... _Types> inline
_Binder<_Unforced, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args)
{ // bind a callable object with an implicit return type
return (_Binder<_Unforced, _Fx, _Types...>(
_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...));
}
// TEMPLATE FUNCTION bind (explicit return type)
template<class _Ret,
class _Fx,
class... _Types> inline
_Binder<_Ret, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args)
{ // bind a callable object with an explicit return type
return (_Binder<_Ret, _Fx, _Types...>(
_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...));
}
我们使用bind库的入口就是使用bind模板函数,实际上这个函数将我们传递的函数地址和函数参数做一个包装,构造一个类,返回个类的一个实例。
_Binder类
template<class _Ret,
class _Fx,
class... _Types>
class _Binder
: public _Binder_result_type<_Ret, _Fx>::type
{ // wrap bound callable object and arguments
private:
typedef make_integer_sequence<size_t, sizeof...(_Types)> _Seq;
typedef typename decay<_Fx>::type _First;
typedef tuple<typename decay<_Types>::type...> _Second;
_Compressed_pair<_First, _Second> _Mypair;
public:
explicit _Binder(_Fx&& _Func, _Types&&... _Args)
: _Mypair(_One_then_variadic_args_t(),
_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...)
{ // construct from forwarded callable object and arguments
}
#define _BINDER_OPERATOR(CONST_OPT) \
template<class... _Unbound> \
auto operator()(_Unbound&&... _Unbargs) CONST_OPT \
-> decltype(_Call_binder(_Forced<_Ret>(), _Seq(), \
_Mypair._Get_first(), _Mypair._Get_second(), \
_STD forward_as_tuple(_STD forward<_Unbound>(_Unbargs)...))) \