Hi all,
I having trouble trying start a packaged_task with a function taking a
reference argument.
The following sample program compiles correctly with gcc 5.1.1 (c++
-std=c++11 -pthread -DUSE_PTR -o tt test.cc ) only if USE_PTR is defined
(-DUSE_PTR), i.e. the my_task() is started with a pointer argument.
Trying to start my_task() with a reference argument fails with the
attached log.
It looks like, along the line, the standard library converts the
reference argument into a non-reference copy, which fails, a.o., because
no copy is available - which is exactly why the reference is wanted here.
In fact, the first error is: "In instantiation of ‘struct
std::_Bind_simple<std::packaged_task<int(MyPar&)>(MyPar)>’"
which appears to use MyPar instead of MyPar&
What am I missing, does anyone have any suggestion?
/* ===================================== */
#include <iostream>
#include <utility>
#include <future>
#include <thread>
class MyPar
{
public:
MyPar(int v)
: val{v}
{ }
int foo()
{
return val;
}
private:
MyPar( const MyPar& ) = delete;
MyPar& operator = (const MyPar& ) = delete;
int val;
};
#ifdef USE_PTR
int my_task( MyPar* arg )
{
return arg->foo();
}
#else
int my_task( MyPar& arg )
{
return arg.foo();
}
#
#endif // USE_PTR
int main( )
{
MyPar par(12);
std::cout << "starting task..." << std::endl;
std::packaged_task<decltype(my_task)> pt0{my_task};
std::future<int> f0{pt0.get_future()};
#ifdef USE_PTR
std::thread t1(std::move(pt0), &par);
#else
std::thread t1(std::move(pt0), static_cast<MyPar&>(par));
#endif // USE_PTR
std::cout << "task(s) started." << std::endl;
std::cout << " task result is: " << f0.get() << std::endl;
t1.join();
std::cout << "task completed." << std::endl;
return 0;
}
/* ===================================== */
$ c++ -std=c++11 -pthread -o tt test.cc
In file included from /usr/include/c++/5.1.1/future:38:0,
from test.cc:3:
/usr/include/c++/5.1.1/functional: In instantiation of ‘struct std::_Bind_simple<std::packaged_task<int(MyPar&)>(MyPar)>’:
/usr/include/c++/5.1.1/thread:137:59: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar&}]’
test.cc:54:58: required from here
/usr/include/c++/5.1.1/functional:1505:61: error: no type named ‘type’ in ‘class std::result_of<std::packaged_task<int(MyPar&)>(MyPar)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/5.1.1/functional:1526:9: error: no type named ‘type’ in ‘class std::result_of<std::packaged_task<int(MyPar&)>(MyPar)>’
_M_invoke(_Index_tuple<_Indices...>)
^
/usr/include/c++/5.1.1/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with _UHead = MyPar; long unsigned int _Idx = 1ul; _Head = MyPar]’:
/usr/include/c++/5.1.1/tuple:369:49: required from ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head>&&) [with long unsigned int _Idx = 1ul; _Head = MyPar]’
/usr/include/c++/5.1.1/type_traits:1162:12: required from ‘struct std::__is_nt_constructible_impl<std::_Tuple_impl<1ul, MyPar>, std::_Tuple_impl<1ul, MyPar>&&>’
/usr/include/c++/5.1.1/type_traits:137:12: required from ‘struct std::__and_<std::is_constructible<std::_Tuple_impl<1ul, MyPar>, std::_Tuple_impl<1ul, MyPar>&&>, std::__is_nt_constructible_impl<std::_Tuple_impl<1ul, MyPar>, std::_Tuple_impl<1ul, MyPar>&&> >’
/usr/include/c++/5.1.1/type_traits:1174:12: required from ‘struct std::is_nothrow_constructible<std::_Tuple_impl<1ul, MyPar>, std::_Tuple_impl<1ul, MyPar>&&>’
/usr/include/c++/5.1.1/type_traits:1205:12: required from ‘struct std::__is_nothrow_move_constructible_impl<std::_Tuple_impl<1ul, MyPar>, true>’
/usr/include/c++/5.1.1/type_traits:1211:12: required from ‘struct std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, MyPar> >’
/usr/include/c++/5.1.1/type_traits:137:12: required from ‘struct std::__and_<std::is_nothrow_move_constructible<std::packaged_task<int(MyPar&)> >, std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, MyPar> > >’
/usr/include/c++/5.1.1/tuple:218:7: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head, _Tail ...>&&) [with long unsigned int _Idx = 0ul; _Head = std::packaged_task<int(MyPar&)>; _Tail = {MyPar}]’
/usr/include/c++/5.1.1/functional:1559:41: required from ‘typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<std::packaged_task<int(MyPar&)>(MyPar)>]’
/usr/include/c++/5.1.1/thread:137:59: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar&}]’
test.cc:54:58: required from here
test.cc:20:5: error: ‘MyPar::MyPar(const MyPar&)’ is private
MyPar( const MyPar& ) = delete;
^
In file included from /usr/include/c++/5.1.1/functional:55:0,
from /usr/include/c++/5.1.1/future:38,
from test.cc:3:
/usr/include/c++/5.1.1/tuple:115:42: error: within this context
: _M_head_impl(std::forward<_UHead>(__h)) { }
^
/usr/include/c++/5.1.1/tuple:115:42: error: use of deleted function ‘MyPar::MyPar(const MyPar&)’
test.cc:20:5: note: declared here
MyPar( const MyPar& ) = delete;
^
/usr/include/c++/5.1.1/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const _Head&) [with long unsigned int _Idx = 1ul; _Head = MyPar]’:
/usr/include/c++/5.1.1/tuple:357:21: required from ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(const _Head&) [with long unsigned int _Idx = 1ul; _Head = MyPar]’
/usr/include/c++/5.1.1/tuple:206:44: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 0ul; _Head = std::packaged_task<int(MyPar&)>; _Tail = {MyPar}]’
/usr/include/c++/5.1.1/tuple:606:30: required from ‘constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = std::packaged_task<int(MyPar&)>; _T2 = MyPar]’
/usr/include/c++/5.1.1/functional:1510:72: required from ‘std::_Bind_simple<_Callable(_Args ...)>::_Bind_simple(_Tp&&, _Up&& ...) [with _Tp = std::packaged_task<int(MyPar&)>; _Up = {MyPar&}; _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar}]’
/usr/include/c++/5.1.1/functional:1559:41: required from ‘typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<std::packaged_task<int(MyPar&)>(MyPar)>]’
/usr/include/c++/5.1.1/thread:137:59: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar&}]’
test.cc:54:58: required from here
test.cc:20:5: error: ‘MyPar::MyPar(const MyPar&)’ is private
In file included from /usr/include/c++/5.1.1/functional:55:0,
from /usr/include/c++/5.1.1/future:38,
from test.cc:3:
/usr/include/c++/5.1.1/tuple:108:25: error: within this context
: _M_head_impl(__h) { }
^
/usr/include/c++/5.1.1/tuple:108:25: error: use of deleted function ‘MyPar::MyPar(const MyPar&)’
test.cc:20:5: note: declared here
MyPar( const MyPar& ) = delete;
^
In file included from /usr/include/c++/5.1.1/functional:55:0,
from /usr/include/c++/5.1.1/future:38,
from test.cc:3:
/usr/include/c++/5.1.1/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const _Head&) [with long unsigned int _Idx = 0ul; _Head = std::packaged_task<int(MyPar&)>]’:
/usr/include/c++/5.1.1/tuple:206:44: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 0ul; _Head = std::packaged_task<int(MyPar&)>; _Tail = {MyPar}]’
/usr/include/c++/5.1.1/tuple:606:30: required from ‘constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = std::packaged_task<int(MyPar&)>; _T2 = MyPar]’
/usr/include/c++/5.1.1/functional:1510:72: required from ‘std::_Bind_simple<_Callable(_Args ...)>::_Bind_simple(_Tp&&, _Up&& ...) [with _Tp = std::packaged_task<int(MyPar&)>; _Up = {MyPar&}; _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar}]’
/usr/include/c++/5.1.1/functional:1559:41: required from ‘typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<std::packaged_task<int(MyPar&)>(MyPar)>]’
/usr/include/c++/5.1.1/thread:137:59: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(MyPar&)>; _Args = {MyPar&}]’
test.cc:54:58: required from here
/usr/include/c++/5.1.1/tuple:108:25: error: use of deleted function ‘std::packaged_task<_Res(_ArgTypes ...)>::packaged_task(const std::packaged_task<_Res(_ArgTypes ...)>&) [with _Res = int; _ArgTypes = {MyPar&}]’
: _M_head_impl(__h) { }
^
In file included from test.cc:3:0:
/usr/include/c++/5.1.1/future:1507:7: note: declared here
packaged_task(const packaged_task&) = delete;
^