将boost :: strand包装的处理程序存储在数组中

时间:2018-08-17 05:18:31

标签: c++ boost

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

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:错误:对'(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:错误:将“ const ucb :: Request”绑定到对“ ucb :: Request&”类型的引用会丢弃限定符            unwrapper :: unwrap(f,0)(a [base_type :: a1_],a [base_type :: a2 _]);

我很困惑,因为正如升压文档here中所述,wrap返回的函数对象具有与传递的对象相同的签名,因此我认为可以像对待其他{{1 }}由bind创建。

编辑:尝试发布所有gcc输出here

1 个答案:

答案 0 :(得分:1)

这令人非常困惑,我感到您的痛苦。我本人也陷入了同一个陷阱。

ASIO文档需要进行一些重大改进。

令人困惑的地方在这里:

  

返回值

     

一个函数对象,当调用该函数对象时,将包装的处理程序传递给该链的分派函数。给定具有签名的功能对象:

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

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

再次在这里:

  

被调用时执行与以下代码等效的代码:

已调用并不表示“就像用std::invoke调用一样”

包装的处理程序不是您认为的函数对象。它不适合std::function的原因是因为其调用运算符不是const。在您的情况下,这很幸运,因为如果您没有出现此错误,则您的代码中肯定会有竞争条件。

如何解决?

恐怕您将不得不查看boost源代码以弄清楚如何正确调用处理程序。它没有证件。

更正。

当我说“未记录”时,我的意思当然是“稀疏记录”:

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

请注意,关于如何生成“处理程序”或获取其指针没有任何叙述。源代码是您最好的选择。

解决方法

在您的处理程序函数中存储lambda。需要通过分支分配的那个只需调用this->m_strand.dispatch(...)