【问题标题】:What is occurring at this bind in C++?C++ 中的这个绑定发生了什么?
【发布时间】:2016-09-09 17:45:51
【问题描述】:

我知道这是简单的代码,但我在任何地方都找不到项目或 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);

我只使用过比绑定函数多一个参数的 bind,而不是两个。此外,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. 绑定函数,返回类型为FaceController::onCanonizeSuccess,第一个参数绑定到uri对象,第二个参数传递给绑定函数,然后是onSuccessonFailure和@987654333 @。
  2. 与上面一样的绑定函数,不同之处在于返回类型为FaceController::onCanonizeFailure
  3. m_ioService
  4. TIME_ALLOWED_FOR_CANONIZATION

所以这意味着 FaceUri::canonize 这里被传递了两个函数对象,每个函数对象都有一个参数,还有另外两个东西。然后,当FaceUri::canonize 最终使用该参数调用其onSuccess 时,由于该函数对象绑定到FaceController::onCanonizeSuccess 的返回类型,这就是将被调用的函数。

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

【问题讨论】:

  • 你的理解是正确的。
  • 但我还是不明白“this”在这里做什么。这与什么有关?
  • OnCanonizeSuccess 是一个成员函数。它绑定到“this”指针。
  • 我只是不跟随。 “this”在它所处的上下文中表示什么?
  • 它的意思是“当你调用 onCanonizeSuccess 时,在我调用你的同一个对象上调用它”,即它将回调绑定到当前对象上下文。

标签: c++ function boost-bind stdbind


【解决方案1】:

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

现在,Canonize*Callback 可能是对象(猜测模板),假设在它们上定义了正确的operator()。我想你知道std::bind 背后的基础知识。

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

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

【讨论】:

  • cmets 确实使这一点变得清晰。我非常感谢彻底,快速的答案。继续努力,继续帮助像我这样的白痴学习!谢谢!
猜你喜欢
  • 2015-12-27
  • 2020-12-13
  • 2010-09-25
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多