【问题标题】:Why is this very simple return std::move(thread handle) failing?为什么这个非常简单的 return std::move(thread handle) 失败了?
【发布时间】:2012-04-21 00:50:29
【问题描述】:
#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编译

输出“在没有活动异常的情况下终止调用”,然后程序中止。

这应该有效,不是吗??

【问题讨论】:

  • 右值引用仍然是引用。您不想返回对局部变量的引用。

标签: c++ multithreading c++11 move


【解决方案1】:

您希望按值返回线程,而不是 右值引用

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)只是从左值右值引用的转换操作,但除非你用它来实际上 move 到其他对象中,原始对象保持不变。在原始代码中,您将引用本地对象并退出函数,然后函数内部的std::thread 被销毁并调用terminate(根据std::thread 的合同,对于任何其他对象它会只需返回对已销毁对象的悬空引用)。

【讨论】:

  • "但除非您使用它实际移动到其他对象中"。但是..不是我吗?
  • @mako:不,您使用强制转换来获取引用,但该引用没有被使用(当原始对象仍然存在时)作为移动构造函数/赋值的参数。考虑这个类似的例子:void f() { type t; type&amp;&amp; lr = std::move(t); } 你执行了转换但你没有移动对象。
  • 错名std::move再次罢工。
猜你喜欢
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多