Reputation: 3972
Code like this:
#include <iostream>
#include <future>
#include <thread>
#include <unistd.h>
int foo(int n) {
n = n*1000;
sleep(1);
return n;
}
int main(void) {
std::packaged_task<int (int)> task(std::bind(foo, 3));
std::future<int> f(task.get_future());
std::thread trd(std::move(task));
std::cout << f.get() << std::endl;
return 0;
}
gcc report:
In file included from /usr/include/c++/4.8.2/future:38:0,
from a.cpp:2:
/usr/include/c++/4.8.2/functional: In instantiation of ‘struct std::_Bind_simple<std::packaged_task<int(int)>()>’:
/usr/include/c++/4.8.2/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(int)>; _Args = {}]’
a.cpp:16:33: required from here
/usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<std::packaged_task<int(int)>()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.8.2/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<std::packaged_task<int(int)>()>’
_M_invoke(_Index_tuple<_Indices...>)
^
make: *** [a] Error 1
My gcc version is 4.8.2 on fedora 20
Upvotes: 0
Views: 1460
Reputation: 15524
The function foo
is declared as:
int foo(int);
It has the function type int(int)
(taking a parameter int
and returning int
).
However, the resulting callable returned by std::bind
when you bind 3
to the first parameter has a different function type: int()
, e.g.:
auto func = std::bind(foo, 3) // Bind 3 to the first parameter.
func(); // Calling func requires no parameter.
The template parameter specified when declaring the std::packaged_task
should be specified as int()
, e.g.:
std::packaged_task<int()> task{std::bind(foo, 3)};
Alternatively don't bind the parameter to 3
when constructing the std::packaged_task
, instead supply it directly when creating the std::thread
object:
std::packaged_task<int(int)> task{foo}; // Don't bind 3
auto f = task.get_future();
std::thread trd{std::move(task), 3}; // Supply 3 here instead.
std::cout << f.get() << std::endl;
trd.join()
before returning from function main
.When using std::thread
also use the sleep function from the Standard Library instead of the non-portable sleep
, e.g.:
std::this_thread::sleep_for(std::chrono::seconds(1));
std::move
you should include the header <utility>
in case the other headers don't include it.Upvotes: 2