我正在尝试在数组中存储一些事件处理程序。其中一些被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
答案 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(...)