On 28/08/2015 00:58, Hartmut Kaiser wrote:
Third, the terminology 'consuming' and 'non-consuming' future does not make any sense (to me). More importantly it is by no means Standard-terminology - thus reasoning in terms of those makes it much more difficult for us to talk about the same thing.
future.get() moves the result of the promise from the internal state, thereby consuming it. Further calls to get() or then() fail. shared_future.get() copies the result of the promise from the internal state, thereby not consuming it. Further calls to get() or then() succeed. I find it hard to imagine this being a difficult concept.
I don't see a reason why anybody would do this. If you know (as a user) you need shared ownership you just make it explicit by assigning the boost::future to a boost::shared_future (as you showed in Example A).
His point was that someone might forget and then it becomes a runtime exception, which can be painful to find if it's in a seldom-executed part of the code (perhaps error handling).
future h=async_file("niall.txt"); shared_future h2(h); // Call these continuations when h becomes ready for(size_t n=0; n<100; n++) // Each of these initiates an async read, so queue depth = 100 h2.then(detail::async_read(buffer[n], 1, n*4096));
Sure, but Example A is just fine, as said.
Note that it's not user code calling then() on the futures in most cases -- see the examples. Instead the future is passed as a "precondition" parameter to a wrapper API in the library, which is what actually registers the continuation. I think Niall's point is that it's harder for the wrapper to know whether it's going to be called a single time or multiple times for a given precondition future, so it's safest if that is accepted only as a shared_future. BUT that means that there is absolutely no benefit (and some drawbacks) to returning non-shared futures, as a result (there are only potentially some savings if they're never used as preconditions). I suppose arguably the wrappers could be templated to accept either future or shared_future, which might mitigate that. But perhaps there are reasons why that's undesirable as well.