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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/527413/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:48:33  来源:igfitidea点击:

how boost::function and boost::bind work

c++boostboost-bindboost-function

提问by Fire Lancer

I dislike having magic boxes scattered all over my code...how exactly do these two classes work to allow basically any function to be mapped to a function object even if the function<> has a completely different parameter set to the one im passing to boost::bind

我不喜欢在我的代码中散布魔术盒......这两个类究竟如何工作以允许基本上任何函数映射到函数对象,即使函数<>具有完全不同的参数设置为我传递给的那个 boost::bind

It even works with different calling conventions (i.e. member methods are __thiscallunder VC, but "normal" functions are generally __cdeclor __stdcallfor those that need to be compatible with C.

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

回答by jpalecek

boost::functionallows anything with an operator()with the right signature to be bound as the parameter, and the result of your bind can be called with a parameter int, so it can be bound to function<void(int)>.

boost::function允许将operator()具有正确签名的任何东西绑定为参数,并且可以使用参数调用绑定的结果int,因此它可以绑定到function<void(int)>.

This is how it works (this description applies alike for std::function):

这是它的工作原理(此描述同样适用于std::function):

boost::bind(&klass::member, instance, 0, _1)returns an object like this

boost::bind(&klass::member, instance, 0, _1)返回这样的对象

struct unspecified_type
{
  ... some members ...
  return_type operator()(int i) const { return instance->*&klass::member(0, i);
}

where the return_typeand intare inferred from the signature of klass::member, and the function pointer and bound parameter are in fact stored in the object, but that's not important

其中return_typeint是从 的签名推断出来的klass::member,函数指针和绑定参数实际上存储在对象中,但这并不重要

Now, boost::functiondoesn't do any type checking: It will take any object and any signature you provide in its template parameter, and create an object that's callable according to your signature and calls the object. If that's impossible, it's a compile error.

现在,boost::function不进行任何类型检查:它将采用您在其模板参数中提供的任何对象和任何签名,并根据您的签名创建一个可调用的对象并调用该对象。如果这是不可能的,那就是编译错误。

boost::functionis actually an object like this:

boost::function实际上是一个这样的对象:

template <class Sig>
class function
{
  function_impl<Sig>* f;
public:
  return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};

where the return_typeand argument_typeare extracted from Sig, and fis dynamically allocated on the heap. That's needed to allow completely unrelated objects with different sizes bind to boost::function.

其中return_typeargument_type从 中提取Sig,并f在堆上动态分配。这是允许具有不同大小的完全不相关的对象绑定到boost::function.

function_implis just an abstract class

function_impl只是一个抽象类

template <class Sig>
class function_impl
{
public:
  virtual return_type operator()(argument_type arg0) const=0;
};

The class that does all the work, is a concrete class derived from boost::function. There is one for each type of object you assign to boost::function

完成所有工作的类是从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); }
};

That means in your case, the assignment to boost function:

这意味着在您的情况下,对 boost 函数的分配:

  1. instantiates a type function_impl_concrete<void(int), unspecified_type>(that's compile time, of course)
  2. creates a new object of that type on the heap
  3. assigns this object to the f member of boost::function
  1. 实例化一个类型function_impl_concrete<void(int), unspecified_type>(当然是编译时)
  2. 在堆上创建该类型的新对象
  3. 将此对象分配给 boost::function 的 f 成员

When you call the function object, it calls the virtual function of its implementation object, which will direct the call to your original function.

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

DISCLAIMER: Note that the names in this explanation are deliberately made up. Any resemblance to real persons or characters ... you know it. The purpose was to illustrate the principles.

免责声明:请注意,本解释中的名称是故意编造的。任何与真实人物或角色的相似之处......你知道的。目的是为了说明原则。