2
#include <thread> #include <cassert> #include <iostream> #include <string> #include <future> #include <utility> void ThFun(std::promise<std::string>&& prms) { std::string hello = "Hello From Future!\n"; prms.set_value(hello); } int main() { std::promise<std::string> prms; auto ftr = prms.get_future(); std::thread th(&ThFun, std::move(prms)); std::cout << "Hello from Main\n"; std::string str = ftr.get(); std::cout << str << std::endl; th.join(); return 0; } 

I get this build error.

1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(1140): error C2664: 'void (std::promise<_Ty> &&)' : cannot convert parameter 1 from 'std::promise<_Ty>' to 'std::promise<_Ty> &&' 1> with 1> [ 1> _Ty=std::string 1> ] 1> You cannot bind an lvalue to an rvalue reference 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(1140) : while compiling class template member function 'void std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>::operator ()(void)' 1> with 1> [ 1> _Forced=true, 1> _Ret=void, 1> _Fun=void (__cdecl *const )(std::promise<std::string> &&), 1> _V0_t=std::promise<std::string>, 1> _V1_t=std::_Nil, 1> _V2_t=std::_Nil, 1> _V3_t=std::_Nil, 1> _V4_t=std::_Nil, 1> _V5_t=std::_Nil, 1> <unnamed-symbol>=std::_Nil 1> ] 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(50) : see reference to class template instantiation 'std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' being compiled 1> with 1> [ 1> _Forced=true, 1> _Ret=void, 1> _Fun=void (__cdecl *const )(std::promise<std::string> &&), 1> _V0_t=std::promise<std::string>, 1> _V1_t=std::_Nil, 1> _V2_t=std::_Nil, 1> _V3_t=std::_Nil, 1> _V4_t=std::_Nil, 1> _V5_t=std::_Nil, 1> <unnamed-symbol>=std::_Nil 1> ] 1> c:\users\jim\documents\visual studio 11\projects\promisesandfutures \promisesandfutures\main.cpp(18) : see reference to function template instantiation 'std::thread::thread<void(__cdecl *)(std::promise<_Ty> &&),std::promise<_Ty>>(_Fn,_V0_t &&)' being compiled 1> with 1> [ 1> _Ty=std::string, 1> _Fn=void (__cdecl *)(std::promise<std::string> &&), 1> _V0_t=std::promise<std::string> 1> ] 

I'm using VC11. The error says can't bind an lvalue, but I'm using std::move to make it an rvalue.

Thanks.

Edit std::ref works fine.

1 Answer 1

7

From the error message it looks like VC11 has made the same mistake that gcc did prior to gcc 4.7: using std::bind in the internals of std::thread. std::bind requires that the arguments are copyable, but std::thread does not. This means that move-only types such as std::promise cannot be passed as arguments to a thread.

Indeed, your example works with gcc 4.7, or with MSVC 2010 and my just::thread implementation of the C++11 thread library, but fails with a similar error message with gcc 4.6 when using its native library (gcc 4.6 also works when using just::thread).

Sign up to request clarification or add additional context in comments.

1 Comment

I'll post this as a bug at msft. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.