关于 c :将 boost::strand package的处理程序存储在数组中

Storing handlers wrapped by boost::strand in array

我正在尝试将一些事件处理程序存储在数组中。其中一些被 boost::strand::wrap.

包裹

1
2
3
4
boost::function<void(Request &)> proc_handlers[] = {
    boost::bind(&Service::req_proc_start, this, _1),
    m_strand.wrap(boost::bind(&Service::req_proc_start, this, _1))
};

因此,我遇到了一堆错误,例如

/usr/include/boost/bind/bind.hpp:313:35: error: no match for call to ‘(boost::_mfi::mf1) (ucb::Service*&, const ucb::Request&)’
unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);

/usr/include/boost/bind/bind.hpp:313:35: error: binding ‘const ucb::Request’ to reference of type ‘ucb::Request&’ discards qualifiers
unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);

我很困惑,因为正如 boost 文档中提到的,wrap 返回的函数对象与传递的签名具有相同的签名,所以我假设它可以像其他由 bind 创建的 boost::funcions 一样对待。

编辑:试图在此处发布所有 gcc 输出


这很令人困惑,我能感觉到你的痛苦。我自己也落入了同样的陷阱。

ASIO 文档需要大幅度改进。

令人困惑的地方在这里:

Return Value

A function object that, when invoked, passes the wrapped handler to the strand's dispatch function. Given a function object with the signature:

请注意,在 ASIO 中,"调用"处理程序与简单地调用它不同。

在我看来,package的处理程序根本不应该有 operator(),因为调用它不会将处理程序分派到链。它只是调用函数。

再来一次:

that, when invoked, executes code equivalent to:

invoked 并不意味着"如同用 std::invoke"

调用

package的处理程序不是您想象的函数对象。它不适合 std::function 的原因是它的调用运算符不是 const。这对您来说是幸运的,因为如果您没有遇到此错误,您的代码中肯定会有竞争条件。

如何解决?

恐怕您必须查看 boost 源代码才能弄清楚如何正确调用处理程序。它是无证的。

更正。

当我说"未记录"时,当然是指"记录稀少":

https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/asio_handler_invoke.html

请注意,没有任何关于如何生成"处理程序"或获取指向它的指针的说明。源代码是您最好的选择。

解决方法

将 lambdas 存储在您的处理函数中。需要通过 strand 调度的那个只需要调用 this->m_strand.dispatch(...)

相关讨论

  • 是的,我首先想到的是建议的解决方法。我想这是最简单的方法。
  • 如果它适合 std::function<> ,那么每个人都会陷入擦除 handler-type 的巨大陷阱,并在这样做时实际上破坏了 handler_invoke
  • asio_handler_invoke 在此站点上受到 TannerSansbury 的好评,这里有一个出色的"tie-it-all-together for io_context API"文档:boost.org/doc/libs/develop/libs/beast /doc/html/beast/using_i??o/…
  • @sehe 感谢您的链接。很有帮助。我仍然认为package的处理程序根本不应该有 operator() 。在我看来,这是一个说谎的界面。当我在电子邮件对话中向 Chris Kholhof 提到这一点时,他再也没有跟我说话 🙂
  • 我也怀疑这个地方的设计选择。我相信对于 executor,事情会变得不那么痛苦,因为你可以将处理程序拆分为一个可以存储的元组(calleable,executor)。但我不确定我的所有期望是否正确
  • @sehe ...只是阅读链接中的示例...这很可怕。根据 c 17,必须可以为服务实现者构建一个更明智的 api。
  • 该示例包括所有东西和厨房水槽。而且我认为它更侧重于教授基础知识而不是风格(尽管如果 Asio 采用 handler_pointer<> 实用程序会很好)
  • 哦,还有最后一点,该文档与旧的自定义界面和新的(关联的执行器/分配器)保持兼容性

以上是关于 c :将 boost::strand package的处理程序存储在数组中的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>