I just read:
and noticed it's kind of old and most of the answers regard pre-2011 C++. These days we have syntactic lambdas, which can even deduce the return type, so lazy evaluation seems to boil down to just passing them around: Instead of
auto x = foo();
you execute
auto unevaluted_x = []() { return foo(); };
and then evaluate when/where you need to:
auto x = unevaluted_x();
Seems like there's nothing more to it. However, one of the answers there suggests using futures with asynchronous launching. Can someone lay out why/if futures are significant for lazy-evaluation work, in C++ or more abstractly? It seems as though futures may very well be evaluated eagerly, but simply, say, on another thread, and perhaps with less priority than whatever created them; and anyway, it should be implementation-dependent, right?
Also, are there other modern C++ constructs which are useful to keep in mind in the context of lazy evaluation?
When you write
Each time you want to get the value (when you call
unevaluated_x) it's calculated, wasting computational resources. So, to get rid of this excessive work, it's a good idea to keep track whether or not the lambda has already been called (maybe in other thread, or in a very different place in the codebase). To do so, we need some wrapper around lambda:Please note that this code is just an example and is not thread safe.
But instead of reinventing the wheel, you could just use
std::shared_future:This requires less code to write and supports some other features (like, check whether the value has already been calculated, thread safety, etc).
There's the following text in the standard [futures.async, (3.2)]:
So, you have a guarantee the calculation will not be called before it's needed.