I started playing with the C++11 standard and the in-built threading. From what I gather when the value on a future is gotten, it is done using the move operator giving ownership away from the original object (like the old auto_ptr used to do on assignment). I tested this out by printing out the pointer of the char array inside an std::string object during the thread and printing the pointer after receiving it back in the main. However, the pointers are different. I would appreciate it if someone could tell me why they are different in this simple code and what the code would have to look like for them to be equal:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
#include <string>
#include <thread>
#include <future>
using namespace std;
void thrfut(promise<string>&& promReceived)
{
string strObj("Hello from future");
cout << "Address of char array inside string inside of thread " << (void*)strObj.data() << endl;
promReceived.set_value(strObj);
}
int main(int argc, char** argv)
{
promise<string> promiseOfText;
future<string> futureText = promiseOfText.get_future(); // has to be before creating thread if the promise is passed rvalue reference, should be moved on calling get or not ?
thread threadHandlingPromise(&thrfut, std::move(promiseOfText));
string stringReceived = futureText.get();
cout << "Received from promise through thread: " << stringReceived << endl;
cout << "Address of of char array inside string received from promise in main " << (void*)stringReceived.data() << endl;
threadHandlingPromise.join();
return 0;
}
Here is a sample output
Address of char array inside string inside of thread 0x10ebc9be1
Received from promise through thread: Hello from future
Address of of char array inside string received from promise in main 0x7fff510f68c9
fyi: OS X 10.9.1 w/ Xcode 5 clang++ in Netbeans 8.0 other people have run the code on Ubuntu and Windows and returned the same address.
EDIT (cfr. comments in answers) * * * * *
I tried this:
struct MYC
{ MYC() = default;
~MYC() { delete _pInt; };
MYC(const MYC & myc) { puts("MYC copy"); _pInt = nullptr; if(myc._pInt != nullptr) { _pInt = new int{*myc._pInt}; } }
MYC(MYC && myc) { puts("MYC move"); delete _pInt; _pInt = myc._pInt; myc._pInt = nullptr; }
void setMe(int value) { delete _pInt; _pInt = new int{value} ; }
int * _pInt = nullptr;
};
void thrfut(promise<MYC>&& promReceived)
{
MYC obj;
obj.setMe(5);
cout << "Address of int inside MYC inside thread " << (void*)obj._pInt << endl;
promReceived.set_value(std::move(obj));
}
int main(int argc, char** argv)
{
promise<MYC> promiseOfMYC;
future<MYC> futureMYC = promiseOfMYC.get_future();
thread threadHandlingPromise(&thrfut, std::move(promiseOfMYC));
auto mycReceived = futureMYC.get();
cout << "Address of int inside MYC received from promise in main " << (void*)mycReceived._pInt << endl;
cout << "Value of int inside MYC received from promise in main " << *(mycReceived._pInt) << endl;
threadHandlingPromise.join();
return 0;
}
and got:
Address of int inside MYC inside thread 0x7fd1b9c00110
MYC move
MYC move
Address of int inside MYC received from promise in main 0x7fd1b9c00110
Value of int inside MYC received from promise in main 5
Which confirms the move dynamics for the non-string classes.