2012-04-21 84 views
2
#include <iostream> 
#include <thread> 
using namespace std; 

thread&& launch(){ 
    thread launchee([](){ 
     this_thread::sleep_for(chrono::milliseconds(280)); 
     cout<<"HA!"<<endl; 
    }); 
    return move(launchee); 
} 

int main(int argc, char **argv){ 
    thread mine(launch()); 
    mine.join(); 
} 

g++-4.6 -std=c++0x 1.cpp -o e1 -pthread为什么这很简单返回std :: move(线程句柄)失败?

输出编译“终止叫不活跃异常”,然后程序中止。

这应该工作,不应该吗?

+6

右值引用仍然是引用。你不想返回对局部变量的引用。 – bames53 2012-04-21 01:07:59

回答

9

要返回的值一个线程,而不是右值引用

std::thread launch() { 
    std::thread launchee([](){ 
     std::this_thread::sleep_for(std::chrono::milliseconds(280)); 
     std::cout<<"HA!"<<std::endl; 
    }); 
    return launchee; 
} 

的原因是std::move(和std::forward)只是从铸造操作左值右值参考,但除非您实际使用移动到某个其他对象中,否则原始对象保持不变。然后在原始代码中引用一个本地对象并退出函数,函数内的std::thread然后被销毁并调用terminate(根据合同std::thread,对于任何其他对象,它只会返回一个悬挂引用被摧毁的物体)。

+0

“,但除非您使用它实际移动到其他对象”。 但是..不是吗? – mako 2012-04-21 08:36:40

+1

@mako:不,您正在使用转换获取引用,但该引用没有被用作(而原始对象仍然存在)作为移动构造函数/赋值的参数。考虑这个相似的例子:'void f(){type t;键入&& lr = std :: move(t); }'你执行了演员,但你没有*移动*对象。 – 2012-04-21 14:29:50

+0

错误的'std :: move'再次触发。 – 2014-12-04 19:10:52

相关问题