[英]Boost::ASIO and std::packaged_task
I have the following pieces of C++14 code 我有以下C ++ 14代码
boost::asio::io_service service_;
I want to submit pieces of work into the io_service
, using the following code that takes any function, it's input arguments and returns me a std::future
to the return value. 我想使用下面的代码将任何工作提交到
io_service
,该代码可以使用任何函数,它是输入参数,并向我返回一个std::future
到返回值。
template <typename F, typename... Args>
auto enqueue(F &&f, Args &&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
typedef typename std::result_of<F(Args...)>::type rType;
auto task = std::make_shared<std::packaged_task<rType()>>(std::bind(std::forward<F>(f),
std::forward<Args>(args)...));
std::future<rType> res = task->get_future();
service_.post(task);
return res;
}
This was then called using 然后使用
enqueue([] (int i) {
return i+1;
}, 100);
This doesnt seem to be working. 这似乎不起作用。 I get an error saying that
service_.post()
was not expecting this input. 我收到一条错误消息,说
service_.post()
不需要此输入。
xxxxxxxxxxxxxx:49:3: required from ‘std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> enqueue(F&&, Args&& ...) [with F = main()::<lambda()>::<lambda()>; Args = {int}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]’
xxxxxxxxxxxxxx:44:6: required from here
/usr/include/boost/asio/impl/io_service.hpp:102:3: error: static assertion failed: CompletionHandler type requirements not met
BOOST_ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check;
^
/usr/include/boost/asio/impl/io_service.hpp:85:3: error: no match for call to ‘(std::shared_ptr<std::packaged_task<void()> >) ()’
BOOST_ASIO_COMPLETION_HANDLER_CHECK(CompletionHandler, handler) type_check;
^
As far as I understand the boost::asio
documentation, this can be done. 据我了解
boost::asio
文档,可以做到这一点。 Any ideas? 有任何想法吗?
From the documentation for post()
: 从
post()
的文档中:
handler
处理器
The handler to be called.
要调用的处理程序。 The io_service will make a copy of the handler object as required.
io_service将根据需要复制处理程序对象。 The function signature of the handler must be:
void handler();
处理程序的功能签名必须为:
void handler();
You are passing in a std::shared_ptr<std::packaged_task<int()>>
. 您正在传递
std::shared_ptr<std::packaged_task<int()>>
。 A shared_ptr
doesn't have operator()
defined. shared_ptr
没有定义operator()
。 And packaged_task
unwrapped isn't copyable. 并且已
packaged_task
无法复制。
So in order to make this work, you'll have to make a shared_ptr<promise>
: 因此,为了使这项工作有效,您必须创建一个
shared_ptr<promise>
:
using R = std::result_of_t<F(Args&&...)>;
auto promise = std::make_shared<std::promise<R>>();
std::future<R> res = promise->get_future();
service.post([promise = std::move(promise),
f = std::forward<F>(f),
args = std::make_tuple(std::forward<Args>(args)...)]{
promise->set_value(std::experimental::apply(f, args));
});
return res;
I seem to remember having been bitten by this myself. 我似乎记得自己曾被我咬过。 It's because
std::packaged_task
is not copyable (the copy constructor is explicitly deleted). 这是因为
std::packaged_task
是不可复制的(复制构造函数已显式删除)。
This is because it contains a promise, which is also not copyable - only moveable. 这是因为它包含一个承诺,该承诺也不能复制-只能移动。
asio::io_service
demands that handler objects are copyable. asio::io_service
要求处理程序对象是可复制的。
You may want to consider building your own packaged-task-like function object which keeps a shared_ptr to the promise. 您可能要考虑构建自己的类似于打包任务的函数对象,该对象将shared_ptr保留为promise。 That would be copyable.
那将是可复制的。
The non-void return type is a red herring - don't waste your time with that. 非无效返回类型是红色鲱鱼-不要浪费时间。
documentation of packaged task here: http://en.cppreference.com/w/cpp/thread/packaged_task/packaged_task 打包任务的文档在这里: http : //en.cppreference.com/w/cpp/thread/packaged_task/packaged_task
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.