On 21 Oct 2014 at 18:57, Gavin Lambert wrote:
However, sometimes you will always do:
promise<int> &p; auto f=p.get_future().then([]); // always continue
There a memory allocation and std::function wrap is totally unnecessary because the compiler has sufficient information to construct f statically, except that the present design in N4123 requires it.
This is what I mean by static continuations - ones which always happen unconditionally.
I don't think code like the above would actually occur in the wild. (Or at least if it did, I would regard it as a bug until proven otherwise.)
If you think of heterogeneous sequence libraries such as proposed Boost.Hana or proposed Boost.Expected then static continuations are the norm, not the exception. Moreover, you aren't supposed to know or care what those are given they have unknown type (especially with C++ 14 lambdas which have templated call operators too). Where I had previously gone wrong was that I was thinking of futures as taking concrete known types. This was a mistake. They should also be able to take *unknown* types. Then they can transport heterogeneous sequences across threads too e.g. a tuple of lambda types.
There should be no reason to attach a continuation to the future in code that still has the promise in scope -- it can simply execute that code directly itself before setting the promise's value.
In "normal" code, the future is returned from a method to outside code that has no access to the promise, and it is that outside code that attaches continuations. I don't think that the optimisation you refer to applies in that case.
I am preparing a suite of *primitives* with which one can implement conventional future promise, but also any other kind of future-ish promise-ish object. Libraries are expected to roll their own custom futures, and when_all()/when_any() will still understand and cope with heterogeneous future implementation inputs. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/