2012-04-19 2 views
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; 
} 

이 빌드 오류가 발생합니다.왜 std :: move가 여기서 실패하고 있는지 알 수 있습니까?

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>   ] 

저는 VC11을 사용하고 있습니다. 오류는 좌변 값을 바인딩 할 수 없다고 말하지만, std :: move를 사용하여이를 우변 값으로 만듭니다.

감사합니다.

std :: ref는 정상적으로 작동합니다.

답변

7

VC11이 gcc 4.7 이전에 gcc와 동일한 실수를 한 것처럼 보이는 오류 메시지에서 std::thread의 내부에서 std::bind을 사용합니다. std::bind은 인수를 복사 할 수 있어야하지만 std::thread은 복사 할 수 있어야합니다. 즉, std::promise과 같은 이동 전용 유형은 스레드로 인수로 전달 될 수 없습니다.

실제로 예제는 gcc 4.7 또는 MSVC 2010과 just::thread implementation of the C++11 thread library에서 작동하지만 네이티브 라이브러리 (gcc 4.6은 그냥 thread를 사용할 때도 작동 함)를 사용할 때 gcc 4.6과 유사한 오류 메시지와 함께 실패합니다.

+0

msft에서 버그로 게시 해 드리겠습니다. 감사. – Tavison

관련 문제