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
and int
从签名推断klass::member
,函数指针和绑定参数实际上存储在对象中,但这并不重要
Now, 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
and argument_type
提取自Sig
, and 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>
(当然,这是编译时间)
- 在堆上创建该类型的新对象
- 将此对象分配给 boost::function 的 f 成员
当您调用函数对象时,它会调用其实现对象的虚函数,这会将调用定向到您的原始函数。
免责声明:请注意,本说明中的名称是故意虚构的。与真人或角色的任何相似之处……您都知道。目的是为了说明原理。