C++ 中的这个绑定发生了什么?

What is occurring at this bind in C++?

我知道这是简单的代码,但我无法在任何地方找到项目或 C++ 绑定的非常详细的文档。这是代码:

uri.canonize(bind(&FaceController::onCanonizeSuccess, this, _1, onSuccess, onFailure, uri),
             bind(&FaceController::onCanonizeFailure, this, _1, onSuccess, onFailure, uri),
             m_ioService, TIME_ALLOWED_FOR_CANONIZATION);

我只使用过比绑定函数多一个参数的绑定,而不是两个。此外,uri.canonize 具有此函数签名:

void
FaceUri::canonize(const CanonizeSuccessCallback& onSuccess,
              const CanonizeFailureCallback& onFailure,
              boost::asio::io_service& io, const time::nanoseconds& timeout) const

在兔子洞的更深处,onSuccessonFailure do 用一个参数调用,但我认为这不重要在这里显示所有内容。最后,onCanonizeSuccess 的函数签名是:

void
FaceController::onCanonizeSuccess(const FaceUri& uri,
                              const CommandSuccessCallback& onSuccess,
                              const CommandFailureCallback& onFailure,
                              const FaceUri& request) 

真的,我只是要求有人和我一起解释这个。这是我的理解: uri.canonize 正在传递 4 个参数:

  1. 一个绑定函数,属于return类型FaceController::onCanonizeSuccess,第一个参数绑定到uri对象,第二个参数传递给绑定函数,然后onSuccessonFailureuri
  2. 一个和上面一样的绑定函数,除了 return 类型是 FaceController::onCanonizeFailure.
  3. m_ioService
  4. TIME_ALLOWED_FOR_CANONIZATION

所以这意味着 FaceUri::canonize 传递了两个函数对象,每个函数对象都有 1 个参数,以及另外两个东西。然后,当 FaceUri::canonize 最终使用那个参数调用它的 onSuccess 时,因为该函数对象绑定到 FaceController::onCanonizeSuccess 的 return 类型,这就是将被调用的函数。

这是我理解这里发生的事情的最佳尝试。唯一的问题是 FaceController::onCanonizeSuccess 不是绑定函数。不可能,因为这里的 arity 意味着我们用 return 类型调用 bind,而 this 是要绑定的函数。 this 在这种情况下是什么?最顶层的调用函数? uriuri.canonize?这一切都一清二楚。不幸的是,我不知道我们使用的是哪个绑定,但我相信它是 std::bind,因为我看到一个 using std::bind 子句,其中一些包含 up.

所以, void FaceUri::canonize 是一个被调用的函数。它接受四个参数,即(具有适当的 cv 和 ref 限定符)
CanonizeSuccessCallback - 一个被调用的函数(根据名称猜测,成功时)
CanonizeFailureCallback - 一个被调用的函数(根据名称猜测,失败时)
和两个简单​​的论点,你可能明白。

现在,Canonize*Callback 可能是对象(猜测模板),假设在其上定义了适当的 operator()。我想你知道 std::bind.

背后的基础知识

uri.canonize是一个函数调用,其中前两个参数是函数,在规范化成功时调用,或者失败。

根据onCanonizeSuccess签名,您必须将四个参数传递给std::bind才能实现该功能。好吧,实际上,由于该函数不是静态的,因此它需要类型为 FaceController* 的第五个(或更确切地说是第 null 个)参数,函数 (onCanonizeSuccess) 应在其上调用。

bind(
  &FaceController::onCanonizeSuccess, // non-static member function requiring first argument to be pointer to FaceController instance
  this, // pointer to FaceController instance, that means, the object with function, where uri.canonize is called.
  _1, // actually std::placeholders::_1, meaning, that first argument will be passed when calling bound function                                                                                                             
  onSuccess, // rest of parameters
  onFailure,
  uri
)