mako
mako

Reputation: 1303

Why is this very simple return std::move(thread handle) failing?

#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();
}

compiled with g++-4.6 -std=c++0x 1.cpp -o e1 -pthread

Outputs "terminate called without an active exception", then the program aborts.

This should work, shouldn't it??

Upvotes: 2

Views: 1348

Answers (1)

You want to return a thread by value, not an rvalue-reference:

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

The reason is that std::move (and std::forward) are just a cast operation from an lvalue to an rvalue-reference, but unless you use that to actually move into some other object, the original object remains unmodified. In the original code you are then taking a reference to a local object and exiting the function, the std::thread inside the function is then destroyed and it calls terminate (as per contract of std::thread, for any other object it would just return a dangling reference to a destroyed object).

Upvotes: 9

Related Questions