Using std::future to manipulate objects in C++11 I'm experimenting with std::future, but haven't found any materials that deal with the usecase I have in mind and was hoping someone could either confirm or deny the validity of the approach excerpted below:

class Thing {
private:

    std::string mValue;

public:
    Thing() : mValue( "" ) {}

    void set(const std::string&amp; s)
    {
        mValue = s;
        reverse( mValue.begin(), mValue.end() );
    }

    const std::string&amp; getValue() const
    {
        return mValue;
    }
};

int main(int argc, const char * argv[])
{
    Thing* tA = new Thing();
    Thing* tB = new Thing();
    Thing* tC = new Thing();

    auto tLambda = [](const string&amp; iStr, Thing* oThing) -&gt; Thing* {
        oThing-&gt;set( iStr );
        return oThing;
    };

    future&lt;Thing*&gt; tA1 = async( launch::async, tLambda, "This is a test...A", tA );
    future&lt;Thing*&gt; tB1 = async( launch::async, tLambda, "This is a test...B", tB );
    future&lt;Thing*&gt; tC1 = async( launch::async, tLambda, "This is a test...C", tC );

    future&lt;Thing*&gt; tA2 = async( launch::async, tLambda, tA1.get()-&gt;getValue(), tA );
    future&lt;Thing*&gt; tB2 = async( launch::async, tLambda, tB1.get()-&gt;getValue(), tB );
    future&lt;Thing*&gt; tC2 = async( launch::async, tLambda, tC1.get()-&gt;getValue(), tC );

    cout &lt;&lt; tA2.get()-&gt;getValue() &lt;&lt; endl;
    cout &lt;&lt; tB2.get()-&gt;getValue() &lt;&lt; endl;
    cout &lt;&lt; tC2.get()-&gt;getValue() &lt;&lt; endl;

    return 0;
}


In essence, I'd like to use std::future to update a pre-existing object's member variables rather than initializing and returning a new object (as is shown in most std::future examples I've seen). In the example above, the model seems a little suspect. I would love to hear any thoughts on the best way to achieve this sort of functionality. Ultimately, I would like to embed this in a thread-pool sort of context. 

(Note: On another user's suggestion, this is reposted from Stack Overflow).
There are two things that concern me in the code you offer:


The Thing instances pointed to by tA, tB, tC are leaked. In this case it looks like it would be trivial to address this by stack allocating them, and passing their address to the async calls: Thing tA; async( ... , &amp;tA);
The cross thread synchronization dependencies are not explicitly addressed. Instead it's all implicit by the way the code is written. Any mistake in the code to lead to data races. For example if in creating tB2 it called the wrong get() or pass the wrong Thing*, not only would it be the wrong value, but it might race.


I spent some time trying to figure out if proposed functionality such as Resumable Functions (pdf) would allow this to be nicer, and while I expect resumable functions would help in more general code, in your code I think a bigger problem is the factoring. Namely, since nothing uses the middle state, the code passed to the future should encompass both operations.

auto tLambdaBoth = [](const string&amp; iStr, Thing* oThing) -&gt; Thing* {
    auto pthing = tLambda(iStr, oThing);
    return tLambda(pthing-&gt;getValue(), oThing);
}


And writing this showed me a new angle on my second misgiving. The original code mixed uses of the original pointer and the pointer returned by tLambda. We know that they currently are the same pointer, but assuming that could restrict your options later. In tLambdaBoth I'd rather see return tLambda(pthing-&gt;getValue(), pthing); so why not the same in the original code?

So we can address both points together by avoiding new, and then never reusing the original object; instead it always uses the pointer that's returned from the future:

Thing tA, tB, tC;

// launch futures
std::vector&lt;std::future&lt;Thing*&gt;&gt; fut1;
fut1.emplace_back(async(launch::async, tLambda, "This is a test...A", &amp;tA));
fut1.emplace_back(async(launch::async, tLambda, "This is a test...B", &amp;tB));
fut1.emplace_back(async(launch::async, tLambda, "This is a test...C", &amp;tC));

// launch second set; using values clearly no longer in flight
std::vector&lt;std::future&lt;Thing*&gt;&gt; fut2;
for (auto&amp; fut : fut1)
{
    auto pthing = fut.get();
    fut2.emplace_back(async(launch::async, tLambda, pthing-&gt;getValue(), pthing));
}

// report results
for (auto&amp; fut : fut2)
{
    cout &lt;&lt; fut.get()-&gt;getValue() &lt;&lt; endl;
}


While I definitely like this a lot better, I'm not sure I understand your use case well enough to say whether this addresses it. Perhaps you should digest what I'm saying here, and then clarify your use case if this did not address what you were trying to determine about the validity of your approach.