std :: packaged_task编译错误w / gcc 4.6

时间:2012-06-07 16:52:54

标签: c++ concurrency c++11 g++ std

我正在尝试使用std::packaged_task

在线程中启动一个函数
Query query; /* protobuf object */        

/* fill Query object */

std::packaged_task<SearchResults(Query&)> task([](Query& q) ->SearchResults {
    index::core::Merger merger;
    return merger.search(q);
    });

std::future<SearchResults> ftr = task.get_future();
std::thread(std::move(task),query).detach();

Edit2:再次更新代码以修复错误并包含完整的错误消息。

g ++ - 4.6(在Ubuntu 10.04上)无法编译代码:

In file included from /usr/include/c++/4.6/memory:80:0,
              from ../src/net/QueryConnection.cpp:8:
/usr/include/c++/4.6/functional: In instantiation of ‘std::_Bind_result<void, 
std::packaged_task<SearchResults(Query&)>(Query)>’:
/usr/include/c++/4.6/thread:135:9:   instantiated from ‘std::thread::thread(_Callable&&, 
_Args&& ...) [with _Callable = std::packaged_task<SearchResults(Query&)>, _Args = 
{Query&}]’
../src/net/QueryConnection.cpp:77:36:   instantiated from here
/usr/include/c++/4.6/functional:1365:7: error: ‘std::_Bind_result<_Result, 
_Functor(_Bound_args ...)>::_Bind_result(const std::_Bind_result<_Result, 
_Functor(_Bound_args ...)>&) [with _Result = void, _Functor =   
std::packaged_task<SearchResults(Query&)>, _Bound_args = {Query}, 
std::_Bind_result<_Result, _Functor(_Bound_args ...)> = std::_Bind_result<void, 
std::packaged_task<SearchResults(Query&)>(Query)>]’ declared to take const reference, 
but implicit declaration would take non-const
Build error occurred, build is stopped

我读过这可能是由于一个错误:gcc-mailinglist

我是C ++ / C ++ 11的新手 - 什么是一个好的工作替代品?我只需要启动一个给我未来的线程,后来在get()异步循环中调用boost::asio - 方法。

3 个答案:

答案 0 :(得分:3)

这是GCC 4.6中的一个错误(实际上是C ++ 11标准中的defect),我已经在4.7中修复了这个错误。

作为解决方法,您可以使用std::async

Query query;
std::future<SearchResults> ftr = std::async([](Query& q) ->SearchResults {
      index::core::Merger merger;
      return merger.search(q);
    }, query);

这适用于GCC 4.6,并且创建packaged_task并在分离的线程中运行它更简单,更安全。

答案 1 :(得分:1)

我不知道这些是否是GCC给出的错误的原因,但它们仍然存在问题。

[=](Query& q){
        index::core::Merger merger;
        return merger.search(q);
}

由于此lambda不包含单个return语句,并且未给出显式返回类型,因此它具有void返回类型。我怀疑你打算让它返回一个SearchResults对象。它需要一个Query&参数,因此打包任务的相应签名为SearchResults(Query&)

[=](Query& q) -> SearchResults {
        index::core::Merger merger;
        return merger.search(q);
}

答案 2 :(得分:0)

更新的代码有两个问题:

1)lambda没有正确地说明它的返回类型。您想要的语法是(假设您不需要复制任何局部变量):

[](Query& q) -> SearchResults {
        index::core::Merger merger;
        return merger.search(q);
}

2)鉴于打包的任务需要Query&,那么您需要将对非常量Query的引用作为std::thread构造函数的第二个参数传递,以便它可以是传递给任务。

我不记得的是,如果您可以合法地将非常量Query引用作为std::thread的第二个参数合法地传递,或者您需要使用std::ref(q)以便正确传递第二个参考参考。

如上所述,它试图在没有参数的情况下调用任务,如

所示
  

/ usr / include / c ++ / 4.6 / future:1272:7:注意:候选人需要1个参数,0提供