Boost :: ASIO和std :: packaged_task

时间:2016-02-24 19:58:49

标签: c++ c++11 boost boost-asio variadic-templates

我有以下C ++ 14代码

boost::asio::io_service service_;

我想将部分工作提交到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;
}

然后使用

调用它
enqueue([] (int i) {
  return i+1;
}, 100);

这似乎不起作用。我收到一条错误消息,指出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;
   ^

据我了解boost::asio文档,可以这样做。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

来自post()的文档:

  

<强>处理程序

     

要调用的处理程序。 io_service将根据需要对处理程序对象进行复制。处理程序的函数签名必须是:void handler();

您正在传递std::shared_ptr<std::packaged_task<int()>>shared_ptr未定义operator()packaged_task展开的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;

<script>
    var data =
            [
                {label:1, quarter :'Q1', y:34},
                {label:2, quarter:'Q1', y:20},
                {label:3, quarter:'Q1', y:30},

                {label:1, quarter:'Q2', y:77},
                {label:2, quarter:'Q2', y:52},
                {label:3, quarter:'Q2', y:3},

                {label:1, quarter:'Q3', y:65},
                {label:2, quarter:'Q3', y:12},
                {label:3, quarter:'Q3', y:9},

                {label:1, quarter:'Q4', y:77},
                {label:2, quarter:'Q4', y:34},
                {label:3, quarter:'Q4', y:5}
            ];



    var quater = ["Q1","Q2","Q3","Q4"];
    var sum = 0;
    var arr = [];
    for(var i = 0; i<data.length; i++){
        for(var j = 0; j<data.length; j++){
            if (data[j]['quarter'] == quater[i])
                sum = sum + data[j]['y'];
        }
        percent = data[i]['y']/sum;
        //console.log(percent)
        arr.push({
            'label': data[i]['label'],
            'y': data[i]['y'],
            'quater': data[i]['quarter'],
            'percent': percent
        });
        sum = 0;
    }


    console.log(arr);




</script>

答案 1 :(得分:0)

我似乎记得被自己咬过了。这是因为reverse input = 614qa -> aq416 initialize sum = 0 a -> 10, 10 * 36^0 = 10, sum + 10 = 10 q -> 26, 26 * 36^1 = 936, sum + 936 = 946 4 -> 4, 4 * 36^2 = 5184, sum + 5184 = 6130 1 -> 1, 1 * 36^3 = 46656, sum + 46656 = 52786 6 -> 6, 6 * 36^4 = 10077696, sum + 10077696 = 10130482 不可复制(显式删除了复制构造函数)。

这是因为它包含一个也不可复制的承诺 - 只能移动。

std::packaged_task要求处理程序对象是可复制的。

您可能需要考虑构建自己的类似于打包任务的函数对象,该函数对象将shared_ptr保留在promise中。那是可复制的。

非虚空返回类型是红鲱鱼 - 不要浪费你的时间。

此处打包任务的文档:http://en.cppreference.com/w/cpp/thread/packaged_task/packaged_task