boost :: function和boost :: bind如何工作

时间:2009-02-09 08:28:45

标签: c++ boost boost-bind boost-function

我不喜欢在我的代码中散布着魔术盒......这两个类究竟是如何工作的,即使函数<>有一个完全不同的参数设置为传递给boost::bind

的im

它甚至适用于不同的调用约定(即VC下的成员方法为__thiscall,但对于需要与C兼容的那些,“普通”函数通常为__cdecl__stdcall

1 个答案:

答案 0 :(得分:94)

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_typeint是从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中提取argument_typeSig,并在堆上动态分配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函数:

  1. 实例化类型function_impl_concrete<void(int), unspecified_type>(当然是编译时间)
  2. 在堆上创建该类型的新对象
  3. 将此对象分配给boost :: function
  4. 的f成员

    调用函数对象时,它会调用其实现对象的虚函数,该函数会将调用指向原始函数。

    免责声明:请注意,本说明中的名称是故意编制的。与真人或人物有任何相似之处......你知道吗。目的是说明原则。