Reputation: 423
I want to construct an object Delay
asynchronously and then (from another thread) repeatedly call a function foo
from that object.
struct Delay {
Delay(int d) {
sleep(d);
}
void foo() { }
};
struct Test {
Test() {
x = async(std::launch::async,
[&]() {return std::make_unique<Delay>(4);});
}
void run() { x.get()->foo(); }
std::future<std::unique_ptr<Delay>> x;
};
int main() {
auto t = Test();
// do other stuff...
t.run();
t.run(); // throwing an instance of 'std::future_error', "No associated state"
return 0;
}
However, obviously, the second time x.get() gets called, an exception is thrown.
What is the recommended way to deal with such a situation? Using a flag as shown below seems like a hack. Is there a better way?
bool is_set = false;
std::unique_ptr<Delay> ptr;
void run_ptr() {
if (!is_set) {
ptr = x.get();
is_set = true;
}
ptr->out();
}
Upvotes: 0
Views: 1784
Reputation: 275310
std::shared_future
is the recommended way to deal with such a situation.
It can be constructed by moving from a future, and supports multiple readers of its state. It is a distinct object because the one-deliver future had certain performance improvements, and because it is so trivial to make a shared future if you need it.
Simply change the type of x
to shared_future<std::unique_ptr<Delay>>
and you are done.
Note, however, that in your above case the unique_ptr
layer is mostly pointless. Probably in your real problem it is not.
Upvotes: 1