Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::packaged_task compile error w/ gcc 4.6

I'm trying to launch a function in a thread using 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: Updated the code again to fix errors and included the full error message.

g++-4.6 (on Ubuntu 10.04) is unable to compile the code:

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

I've read that this is maybe due to a bug: gcc-mailinglist

I'm new to C++ / C++11 - What would be a good working alternative? I just need to launch a thread that gives me a future, whom get()-method is called later in an boost::asio async loop.

like image 342
kei1aeh5quahQu4U Avatar asked Oct 08 '22 14:10

kei1aeh5quahQu4U


2 Answers

It is a bug in GCC 4.6 (actually a defect in the C++11 standard) which I've already fixed in 4.7.

As a workaround you can use std::async

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

This works OK with GCC 4.6, and is simpler and safer that creating a packaged_task and running it in a detached thread anyway.

like image 78
Jonathan Wakely Avatar answered Oct 12 '22 12:10

Jonathan Wakely


I don't know if these are the cause of the errors GCC is giving, but they are problematic nonetheless.

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

Since this lambda doesn't consist of a single return statement, and no explicit return type was given, it has a void return type. I suspect you intended it to return a SearchResults object. And it takes a Query& parameter, so the appropriate signature for the packaged task would be SearchResults(Query&).

[=](Query& q) -> SearchResults {
        index::core::Merger merger;
        return merger.search(q);
}
like image 25
R. Martinho Fernandes Avatar answered Oct 12 '22 12:10

R. Martinho Fernandes