5

我正在尝试使用在线程中启动一个函数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异步循环中调用 who -method。

4

3 回答 3

3

这是 GCC 4.6 中的一个错误(实际上是 C++11 标准中的一个缺陷),我已经在 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无论如何创建并在分离线程中运行它更简单、更安全。

于 2012-06-07T21:28:20.747 回答
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);
}
于 2012-06-07T18:44:36.533 回答
0

更新后的代码有两个问题:

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

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

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

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

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

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

于 2012-06-07T20:48:36.780 回答