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;
}

我得到这个构建错误。

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 工作正常。

4

1 回答 1

7

从错误消息看来,VC11 犯了与 gcc 4.7 之前的 gcc 相同的错误:std::bindstd::thread. std::bind要求参数是可复制的,但std::thread不是。这意味着只能移动类型,例如std::promise不能作为参数传递给线程。

事实上,您的示例适用于 gcc 4.7,或 MSVC 2010 和我的 C++11 线程库的 just::thread 实现,但在使用其本机库时失败并出现与 gcc 4.6 类似的错误消息(gcc 4.6 也适用于仅使用::thread)。

于 2012-04-19T12:15:31.333 回答