C++ optional<> and delayed construction of noncopyable object - c++

See the below code,
The question is: how can I delay the construction of an object that is non-copyable, using optional<>.
I'm using boost::optional in the example, although I believe its now in the std::optional standard too.
Yes, I could use scoped_ptr<>, however I wanted to allocate on the stack, not the heap.
#include <boost/optional.hpp>
#include <boost/utility.hpp>
using namespace boost;
struct HardFoo : noncopyable { };
int main()
{
optional<HardFoo> ok_1( in_place() ); // OK
// optional<HardFoo> no_1( HardFoo() ); // won't compile
optional<HardFoo> delay_construct;
// delay_construct = HardFoo(); // won't compile
// delay_construct = optional<HardFoo>( in_place() ); // won't compile
// delay_construct.swap( optional<HardFoo>( in_place() ) ); // won't compile
return 0;
}
I'm using g++, I assume it wouldn't matter whether its C++03 or C++11 in this case, as its a fundamental design issue rather than just a stuff up in the code.
As requested, some error messages, for this one, I uncommented:
delay_construct = HardFoo();
$ g++ -g -Wall -o test -I/stuff/boost/ test.cpp
In file included from /stuff/boost/utility.hpp:18:0,
from test.cpp:2:
test.cpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::assign_value(boost::optional_detail::optional_base<T>::argument_type, boost::optional_detail::optional_base<T>::is_not_reference_tag) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&; boost::optional_detail::optional_base<T>::is_not_reference_tag = mpl_::bool_<false>]’:
/stuff/boost/optional/optional.hpp:307:12: required from ‘void boost::optional_detail::optional_base<T>::assign(boost::optional_detail::optional_base<T>::argument_type) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&]’
/stuff/boost/optional/optional.hpp:606:9: required from ‘boost::optional<T>& boost::optional<T>::operator=(boost::optional<T>::argument_type) [with T = HardFoo; boost::optional<T> = boost::optional<HardFoo>; boost::optional<T>::argument_type = const HardFoo&]’
test.cpp:14:30: required from here
/stuff/boost/noncopyable.hpp:28:26: error: ‘const boost::noncopyable_::noncopyable& boost::noncopyable_::noncopyable::operator=(const boost::noncopyable_::noncopyable&)’ is private
test.cpp:6:8: error: within this context
In file included from /stuff/boost/optional.hpp:15:0,
from test.cpp:1:
/stuff/boost/optional/optional.hpp:433:69: note: synthesized method ‘HardFoo& HardFoo::operator=(const HardFoo&)’ first required here
In file included from /stuff/boost/utility.hpp:18:0,
from test.cpp:2:
test.cpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::construct(boost::optional_detail::optional_base<T>::argument_type) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&]’:
/stuff/boost/optional/optional.hpp:308:12: required from ‘void boost::optional_detail::optional_base<T>::assign(boost::optional_detail::optional_base<T>::argument_type) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&]’
/stuff/boost/optional/optional.hpp:606:9: required from ‘boost::optional<T>& boost::optional<T>::operator=(boost::optional<T>::argument_type) [with T = HardFoo; boost::optional<T> = boost::optional<HardFoo>; boost::optional<T>::argument_type = const HardFoo&]’
test.cpp:14:30: required from here
/stuff/boost/noncopyable.hpp:27:7: error: ‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’ is private
test.cpp:6:8: error: within this context
In file included from /stuff/boost/optional.hpp:15:0,
from test.cpp:1:
/stuff/boost/optional/optional.hpp:346:8: note: synthesized method ‘HardFoo::HardFoo(const HardFoo&)’ first required here
There is an answer suggesting to use in_place directly,
it works with this:
optional<HardFoo> ok( in_place() );
but not this:
optional<HardFoo> no( in_place<HardFoo>() ); // BAD
The error messages:
$ g++ -g -Wall -o test -I/stuff/boost/ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:15:44: error: no matching function for call to ‘in_place()’
test.cpp:15:44: note: candidates are:
In file included from /stuff/boost/preprocessor/iteration/detail/iter/forward1.hpp:52:0,
from /stuff/boost/utility/in_place_factory.hpp:24,
from /stuff/boost/optional/optional.hpp:37,
from /stuff/boost/optional.hpp:15,
from test.cpp:1:
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template<class A0> boost::in_place_factory1<A0> boost::in_place(const A0&)
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template argument deduction/substitution failed:
test.cpp:15:44: note: candidate expects 1 argument, 0 provided
In file included from /stuff/boost/preprocessor/iteration/detail/iter/forward1.hpp:57:0,
from /stuff/boost/utility/in_place_factory.hpp:24,
from /stuff/boost/optional/optional.hpp:37,
from /stuff/boost/optional.hpp:15,
from test.cpp:1:
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template<class A0, class A1> boost::in_place_factory2<A0, A1> boost::in_place(const A0&, const A1&)
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template argument deduction/substitution failed:
test.cpp:15:44: note: candidate expects 2 arguments, 0 provided
In file included from /stuff/boost/preprocessor/iteration/detail/iter/forward1.hpp:62:0,
from /stuff/boost/utility/in_place_factory.hpp:24,
from /stuff/boost/optional/optional.hpp:37,
from /stuff/boost/optional.hpp:15,
from test.cpp:1:

You need to in_place directly into the object:
delay_construct = boost::in_place<Type>(params);
Note that it appears that boost didn't support default construction through factories (nullary factories) until 1.35.

In C++14, we will have std::optional, which happens to have std::optional::emplace. So you can do:
std::optional<HardFoo> delay_construct;
delay_construct.emplace(constructor_arg_1, constructor_arg_2);

Related

std::optional::emplace() to default construct an optional does not work in clang?

I have a construct similar to the following in my code.
#include <optional>
struct C {
struct C2 {
bool b { false };
};
std::optional<C2> oc2;
};
int main(int argc, char** argv) {
C c;
c.oc2.emplace(); // clang error!
}
It's an std::optional object inside of a class that I want to initialize via its default constructor. The above code compiles fine in GCC 9. But Clang 9 fails with the following error:
% clang++-9 -std=c++17 -o main main.cpp
main.cpp:13:11: error: no matching member function for call to 'emplace'
c.oc2.emplace();
~~~~~~^~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/optional:845:2: note: candidate template ignored: requirement 'is_constructible_v<C::C2>' was not satisfied [with _Args = <>]
emplace(_Args&&... __args)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/optional:855:2: note: candidate function template not viable: requires at least argument '__il', but no arguments were provided
emplace(initializer_list<_Up> __il, _Args&&... __args)
^
1 error generated.
Is this a Clang bug or is there a better way to initialize an optional value in that case?

Simple C++11 hash function won't compile

The following code for a simple hash function won't compile
#include <cstddef>
#include <functional>
namespace {
struct Foo {
long i;
};
}
namespace std {
template<> struct hash<::Foo> {
size_t operator()(::Foo foo) const {
return hash<decltype(foo.i)>(foo.i);
}
};
}
My 4.8.5 g++ compiler emits these messages:
$ g++ -std=c++11 a.cpp
a.cpp: In member function ‘std::size_t std::hash<{anonymous}::Foo>::operator()({anonymous}::Foo) const’:
a.cpp:13:47: error: no matching function for call to ‘std::hash<long int>::hash(long int&)’
return hash<decltype(foo.i)>(foo.i);
^
a.cpp:13:47: note: candidates are:
In file included from /usr/include/c++/4.8.2/bits/basic_string.h:3033:0,
from /usr/include/c++/4.8.2/string:52,
from /usr/include/c++/4.8.2/stdexcept:39,
from /usr/include/c++/4.8.2/array:38,
from /usr/include/c++/4.8.2/tuple:39,
from /usr/include/c++/4.8.2/functional:55,
from a.cpp:2:
/usr/include/c++/4.8.2/bits/functional_hash.h:107:3: note: constexpr std::hash<long int>::hash()
_Cxx_hashtable_define_trivial_hash(long)
^
/usr/include/c++/4.8.2/bits/functional_hash.h:107:3: note: candidate expects 0 arguments, 1 provided
/usr/include/c++/4.8.2/bits/functional_hash.h:107:3: note: constexpr std::hash<long int>::hash(const std::hash<long int>&)
/usr/include/c++/4.8.2/bits/functional_hash.h:107:3: note: no known conversion for argument 1 from ‘long int’ to ‘const std::hash<long int>&’
/usr/include/c++/4.8.2/bits/functional_hash.h:107:3: note: constexpr std::hash<long int>::hash(std::hash<long int>&&)
/usr/include/c++/4.8.2/bits/functional_hash.h:107:3: note: no known conversion for argument 1 from ‘long int’ to ‘std::hash<long int>&&’
$ fg
The problem appears to be the call-by-reference in the first error message but I don't understand why or how to fix it.
You are missing a set of parentheses in
return hash<decltype(foo.i)>(foo.i);
In the above you are trying to construct a std::hash, not call its operator(). You need
return hash<decltype(foo.i)>()(foo.i);
// or
return hash<decltype(foo.i)>{}(foo.i);
where the empty set of parentheses/curly braces constructs the hash object, and the second set calls its operator()

Error while appling std::bind to function with argument <boost::asio::ip::tcp::socket>?

There's a function accepting an argument with type boost::asio::ip::tcp::socket. But I failed to apply std::bind to it. I've checked template arguments in std::_Bind_helper but no problem found. I've tried both gcc 8.1.0 and clang 6.0.0, and they give the same error.
#include <functional>
#include <boost/asio.hpp>
using namespace std;
namespace asio = boost::asio;
using tcp = asio::ip::tcp;
int c;
void good_f(int) {c=1;}
void good() {
using typeA = int;
auto helper = std::bind(&good_f, typeA(1));
helper();
// OK
}
void fixed_f(tcp::socket &) {c=1;}
void fixed() {
using type1 = tcp::socket;
asio::io_context ioc;
tcp::socket sock(ioc);
auto helper = std::bind(&fixed_f, std::ref(sock));
helper();
// OK
}
void fail_f(tcp::socket &&) {c=1;}
void fail() {
using type1 = tcp::socket;
asio::io_context ioc;
tcp::socket sock(ioc);
// fail_f(std::move(sock));
// OK
auto helper = std::bind(&fail_f, std::move(sock));
helper();
// a.cc:34:5: error: no matching function for call to object of type 'std::_Bind<void (*(boost::asio::basic_stream_socket<boost::asio::ip::tcp>))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
// helper();
// ^~~~~~
}
Compilation log and errors:
recolic#RECOLICPC ~/tmp> clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
recolic#RECOLICPC ~/tmp> clang++ -c a.cc
a.cc:39:5: error: no matching function for call to object of type 'std::_Bind<void (*(boost::asio::basic_stream_socket<boost::asio::ip::tcp>))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
helper();
^~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:480:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void
(*&(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
operator()(_Args&&... __args)
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:491:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void (*const &(const
boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
operator()(_Args&&... __args) const
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:509:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void (*volatile &(volatile
boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
operator()(_Args&&... __args) volatile
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:521:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void (*const volatile &(const volatile
boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
operator()(_Args&&... __args) const volatile
^
1 error generated.
I'm not sure what caused this error. Could you please give me any suggestions?
void fail_f_1(tcp::socket);
std::bind(&fail_f_1, tcp::socket(io_context));
This solution fails because boost::asio::ip::tcp::socket is noncopyable.
void fail_f_2(tcp::socket &&);
std::bind(&fail_f_2, std::move(tcp::socket(io_context)));
This solution fails because std::bind pass bound arguments as lvalues, rather than rvalue. fixed_f is a good solution.
If you have to pass rvalue-reference as bound argument, this answer will help.

cpprest/pplx : call to implicitly-deleted default constructor of '_ResultHolder<SomeObj>'

I am currently using the cpprest API found at https://casablanca.codeplex.com/ for a simple RESTful API project.
This popular library uses Microsoft's PPLX framework to facilitate the async tasks.
I am currently encountering an issue in which code does not compile when a function returns an object of type pplx::task<SomeObj> and SomeObj has no default constructor. My understanding is that this code should be a valid as no default objects should be created.
Is there an error in my code or is this a bug?
Example Code:
#include <vector>
#include <string>
#include <cpprest/http_client.h>
class SomeSubObj {
public:
int a,b,c;
SomeSubObj(int a, int b, int c): a(a), b(b), c(c){}
};
class SomeObj {
public:
std::vector<SomeSubObj> subObjs;
SomeObj(std::string json){
// Populate from JSON...
subObjs.push_back(SomeSubObj(1,1,1));
subObjs.push_back(SomeSubObj(2,2,2));
subObjs.push_back(SomeSubObj(3,3,3));
}
};
pplx::task<SomeObj> doSomething(){
return pplx::task<std::string>([]() {
// Make a call out and get some json...
return std::string("{...}");
}).then([](std::string x) {
// Return a transformed object
return SomeObj("...");
});
}
int main()
{
doSomething();
return 0;
}
I am currently receiving the following output:
g++ -std=c++0x -Iboost_thread-mt -Iboost_atomic -Iboost_system -Icpprest -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Bug.d" -MT"src/Bug.d" -o "src/Bug.o" "../src/Bug.cpp"
In file included from ../src/Bug.cpp:4:
In file included from /usr/local/include/cpprest/http_client.h:44:
/usr/local/include/pplx/pplxtasks.h:2404:9: error: call to implicitly-deleted default constructor of '_ResultHolder<SomeObj>'
_Task_impl(_CancellationTokenState * _Ct, scheduler_ptr _Scheduler_arg)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2096:15: note: in instantiation of member function 'pplx::details::_Task_impl<SomeObj>::_Task_impl' requested here
__second_(_VSTD::forward<_Args2>(get<_I2>(__second_args))...)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:2359:15: note: in instantiation of function template specialization 'std::__1::__libcpp_compressed_pair_imp<std::__1::allocator<pplx::details::_Task_impl<SomeObj> >, pplx::details::_Task_impl<SomeObj>, 1>::__libcpp_compressed_pair_imp<std::__1::allocator<pplx::details::_Task_impl<SomeObj> > &, pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &, 0, 0, 1>' requested here
: base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:3697:16: note: in instantiation of function template specialization 'std::__1::__compressed_pair<std::__1::allocator<pplx::details::_Task_impl<SomeObj> >, pplx::details::_Task_impl<SomeObj> >::__compressed_pair<std::__1::allocator<pplx::details::_Task_impl<SomeObj> > &, pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &>' requested here
: __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4271:26: note: in instantiation of function template specialization 'std::__1::__shared_ptr_emplace<pplx::details::_Task_impl<SomeObj>, std::__1::allocator<pplx::details::_Task_impl<SomeObj> > >::__shared_ptr_emplace<pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &>' requested here
::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4630:29: note: in instantiation of function template specialization 'std::__1::shared_ptr<pplx::details::_Task_impl<SomeObj> >::make_shared<pplx::details::_CancellationTokenState *&, pplx::scheduler_ptr &>' requested here
return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
^
/usr/local/include/pplx/pplxtasks.h:1429:103: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
static _Type _Make(_CancellationTokenState * _Ct, scheduler_ptr _Scheduler_arg) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct, _Scheduler_arg); }
^
/usr/local/include/pplx/pplxtasks.h:3623:52: note: in instantiation of member function 'pplx::details::_Task_ptr<SomeObj>::_Make' requested here
_M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct, _Scheduler);
^
/usr/local/include/pplx/pplxtasks.h:4138:27: note: in instantiation of member function 'pplx::task<SomeObj>::_CreateImpl' requested here
_ContinuationTask._CreateImpl(_PTokenState, _Scheduler);
^
/usr/local/include/pplx/pplxtasks.h:4101:16: note: in instantiation of function template specialization 'pplx::task<std::__1::basic_string<char> >::_ThenImpl<std::__1::basic_string<char>, <lambda at ../src/Bug.cpp:27:10> >' requested here
return _ThenImpl<_InternalReturnType, _Function>(_Func, _PTokenState, _TaskOptions.get_continuation_context(), _Scheduler, _CreationStack);
^
/usr/local/include/pplx/pplxtasks.h:3424:16: note: in instantiation of function template specialization 'pplx::task<std::__1::basic_string<char> >::_ThenImpl<std::__1::basic_string<char>, <lambda at ../src/Bug.cpp:27:10> >' requested here
return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions);
^
../src/Bug.cpp:27:5: note: in instantiation of function template specialization 'pplx::task<std::__1::basic_string<char> >::then<<lambda at ../src/Bug.cpp:27:10> >' requested here
}).then([](std::string x) {
^
/usr/local/include/pplx/pplxtasks.h:844:15: note: default constructor of '_ResultHolder<SomeObj>' is implicitly deleted because field '_Result' has no default constructor
_Type _Result;
^
1 error generated.
make: *** [src/Bug.o] Error 1

std::packaged_task::reset example from http://www.cplusplus.com doesn't work

I tried to compile and run example of reset() function from http://www.cplusplus.com/reference/future/packaged_task/reset/:
$ cat task.cpp
// packaged_task::get_future
#include <iostream> // std::cout
#include <utility> // std::move
#include <future> // std::packaged_task, std::future
#include <thread> // std::thread
// a simple task:
int triple (int x) { return x*3; }
int main ()
{
std::packaged_task<int(int)> tsk (triple); // package task
std::future<int> fut = tsk.get_future();
std::thread (std::move(tsk),33).detach();
std::cout << "The triple of 33 is " << fut.get() << ".\n";
// re-use same task object:
tsk.reset();
fut = tsk.get_future();
std::thread(std::move(tsk),99).detach();
std::cout << "Thre triple of 99 is " << fut.get() << ".\n";
return 0;
}
but I got either compiler error or runtime error, depending on compiler used:
GCC:
$ g++ -o task -std=c++11 -I/opt/local/include task.cpp && ./task
The triple of 33 is 99.
terminate called after throwing an instance of 'std::future_error'
what(): No associated state
[1] 14850 abort ./task
CLANG:
$ clang++ -o task -std=c++11 -stdlib=libc++ -I/opt/local/include task.cpp && ./task
In file included from task.cpp:2:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/iostream:38:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/ios:216:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/__locale:15:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/string:439:
In file included from /opt/local/libexec/llvm-3.4/bin/../include/c++/v1/algorithm:627:
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1627:45: error: multiple overloads of 'address' instantiate to the same
signature 'const_pointer (const_reference) const noexcept'
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/type_traits:922:38: note: in instantiation of template class
'std::__1::allocator<int (int)>' requested here
: public integral_constant<bool, __is_empty(_Tp)> {};
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1908:40: note: in instantiation of template class
'std::__1::is_empty<std::__1::allocator<int (int)> >' requested here
bool = is_empty<_T2>::value
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1930:44: note: in instantiation of default argument for
'__libcpp_compressed_pair_switch<int (int), std::__1::allocator<int (int)>, false, false>' required here
template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:2298:15: note: in instantiation of default argument for
'__libcpp_compressed_pair_imp<int (int), std::__1::allocator<int (int)> >' required here
: private __libcpp_compressed_pair_imp<_T1, _T2>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1770:36: note: in instantiation of template class
'std::__1::__compressed_pair<int (int), std::__1::allocator<int (int)> >' requested here
__compressed_pair<_Fp, _Alloc> __f_;
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1877:9: note: in instantiation of template class
'std::__1::__packaged_task_func<int (int), std::__1::allocator<int (int)>, int (int)>' requested here
if (sizeof(_FF) <= sizeof(__buf_))
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:2026:45: note: in instantiation of function template specialization
'std::__1::__packaged_task_function<int (int)>::__packaged_task_function<int (&)(int)>' requested here
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
^
task.cpp:12:32: note: in instantiation of function template specialization 'std::__1::packaged_task<int
(int)>::packaged_task<int (&)(int), void>' requested here
std::packaged_task<int(int)> tsk (triple); // package task
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:1625:39: note: previous declaration is here
_LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:2121:9: error: data member instantiated with function type 'int (int)'
_T1 __first_;
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/memory:2298:15: note: in instantiation of template class
'std::__1::__libcpp_compressed_pair_imp<int (int), std::__1::allocator<int (int)>, 2>' requested here
: private __libcpp_compressed_pair_imp<_T1, _T2>
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1770:36: note: in instantiation of template class
'std::__1::__compressed_pair<int (int), std::__1::allocator<int (int)> >' requested here
__compressed_pair<_Fp, _Alloc> __f_;
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:1877:9: note: in instantiation of template class
'std::__1::__packaged_task_func<int (int), std::__1::allocator<int (int)>, int (int)>' requested here
if (sizeof(_FF) <= sizeof(__buf_))
^
/opt/local/libexec/llvm-3.4/bin/../include/c++/v1/future:2026:45: note: in instantiation of function template specialization
'std::__1::__packaged_task_function<int (int)>::__packaged_task_function<int (&)(int)>' requested here
explicit packaged_task(_Fp&& __f) : __f_(_VSTD::forward<_Fp>(__f)) {}
^
task.cpp:12:32: note: in instantiation of function template specialization 'std::__1::packaged_task<int
(int)>::packaged_task<int (&)(int), void>' requested here
std::packaged_task<int(int)> tsk (triple); // package task
^
2 errors generated.
I'm using OSX Maverics and compilers:
$ g++ --version
g++ (MacPorts gcc48 4.8.2_0) 4.8.2
$ clang++ --version
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
Could someone please help me?
GCC is correct:
std::thread (std::move(tsk),33).detach(); // 1
//...
tsk.reset(); // 2
After (1), tsk has no more state (per move constructor of packaged_task)
At (2), reset() is required to throw the no_state std::future_error
clang had a bug, as pointed out in the comments.