What is std::promise? -- StackOverflow

Inquiring minds want to know this classic question:

What is std::promise?

I'm fairly familiar with the new standard library's std::thread, std::async and std::future components (e.g. see this answer), which are straight-forward.

However, I cannot quite grasp what std::promise is, what it does and in which situations it is best used. The standard document itself doesn't contain a whole lot of information beyond its class synopsis, and neither does just::thread.

Could someone please give a brief, succinct example of a situation where an std::promise is needed and where it is the most idiomatic solution?

Add a Comment

Comments are closed.

Comments (2)

0 0

wonderyl said on Jul 14, 2013 02:42 AM:

I's confused at first, but when I change the name from "Promise" to "Wish", it all makes sense.
One can make a wish, name dispatch the wish to others to work it out, and wait for the wish to come true. What a happy life.
0 0

Sigismondo said on Jul 15, 2013 10:11 AM:

Hi,
the promise is the tool you need to create, return and asynchronously assign a result to a future. You don't need it when using std::async/std::packaged_task because the promise is embedded into them - you are just using the returned future.

For the usage, I will show by example:


#include <iostream>
#include <future>
#include <list>

class OneTask {
std::promise<std::list<int> > resList;
public:
void Execute(int x) {
std::list<int> res;
for(int i=0; i<x; ++i) {
res.push_back(i);
}
resList.set_value(move(res));
}
std::future<std::list<int> > Result() {
return resList.get_future();
}
};


int main(int argc, char **argv) {
OneTask ot;
std::future<std::list<int> > fut = ot.Result();
std::thread th(&OneTask::Execute,&ot,2);
// ...
std::list<int> res = fut.get();
int r = res.size();
std::cout << r << std::endl;
th.join();
}


When you need more results, not necessarily at the completion of the task, you need to use promise's.

It's important to note that we should avoid to perform copies: future::get() uses move semantics, so it does promise::set_value(). We just need to use the correct move() there and we have never copied the elements around - the 2 items returned to the main thread are "physically" the same ones pushed back in the Execute() method.

In general OneTask kind of objects must be created, executed, the results got and finally destroyed: promises and futures are one-shot objects - cannot be reused.