我不喜欢魔术盒散布在我的代码中......这两个类究竟如何工作以允许基本上任何函数映射到函数对象,即使函数<>具有与传递给的那个完全不同的参数集boost::bind
它甚至可以使用不同的调用约定(即成员方法__thiscall
在 VC 下,但“普通”函数通常是__cdecl
或__stdcall
用于那些需要与 C 兼容的函数。
我不喜欢魔术盒散布在我的代码中......这两个类究竟如何工作以允许基本上任何函数映射到函数对象,即使函数<>具有与传递给的那个完全不同的参数集boost::bind
它甚至可以使用不同的调用约定(即成员方法__thiscall
在 VC 下,但“普通”函数通常是__cdecl
或__stdcall
用于那些需要与 C 兼容的函数。
boost::function
允许将operator()
具有正确签名的任何东西绑定为参数,并且可以使用参数调用绑定的结果int
,因此可以将其绑定到function<void(int)>
.
这就是它的工作原理(此描述同样适用于std::function
):
boost::bind(&klass::member, instance, 0, _1)
返回一个像这样的对象
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
其中return_type
andint
是从 的签名中推断出来的klass::member
,而函数指针和绑定参数实际上存储在对象中,但这并不重要
现在,boost::function
不进行任何类型检查:它将获取您在其模板参数中提供的任何对象和任何签名,并创建一个可根据您的签名调用的对象并调用该对象。如果这是不可能的,那就是编译错误。
boost::function
实际上是这样的对象:
template <class Sig>
class function
{
function_impl<Sig>* f;
public:
return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};
其中return_type
andargument_type
是从 中提取的Sig
,并且f
是在堆上动态分配的。这是允许具有不同大小的完全不相关的对象绑定到boost::function
.
function_impl
只是一个抽象类
template <class Sig>
class function_impl
{
public:
virtual return_type operator()(argument_type arg0) const=0;
};
完成所有工作的类是派生自boost::function
. 您分配给的每种类型的对象都有一个boost::function
template <class Sig, class Object>
class function_impl_concrete : public function_impl<Sig>
{
Object o
public:
virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); }
};
这意味着在您的情况下,分配给 boost 功能:
function_impl_concrete<void(int), unspecified_type>
(当然是编译时间)当您调用函数对象时,它会调用其实现对象的虚函数,这会将调用定向到您的原始函数。
免责声明:请注意,此解释中的名称是故意编造的。任何与真实人物或角色的相似之处......你知道的。目的是说明原理。