upvote
You are describing a single async step, not a state machine. "Create a promise, set it when done", that's one state. A real async state machine has N states with transitions, branching, error handling, and cleanup between them.

> "The only 'assembly' required is creating the associated promise"

Again, that is only true for one step. For a state machine with N states you need explicit state enums or a long chain of .then() continuations. You also need to the manage the shared state across continuations (normally on the heap). You need to manage manual error propagation across each boundary and handle the cancellation tokens.

You only get a "A nice readable linear flow" using std:future when 1) using a blocking .get() on a thread, or 2) .then() chaining, which isn't "nice" by any means.

Lastly, you seem to be conflating a co_yield (generator, pull-based) with co_await (event-driven, push-based). With co_await, the coroutine is resumed by whoever completes the awaitable.

But what do I know... I only worked on implementing coroutines in cl.exe for 4 years. ;-)

reply
I only mentioned co_yield() since that's what the article was (ab)using, although perhaps justifiably so. It seems the coroutine support was added to C++ in a very flexible way, but so low level as to be daunting/inconvenient to use. It needs to have more high level facilities (like Generators) built on top.

What I was thinking of as a state machine with using std::future was a single function state machine, using switch (state) to the state specific dispatch of asynch ops using std::future, wait for completion then select next state.

reply
> as to be daunting/inconvenient to use

I don't even know how to respond to that. How in the world are you using C++ professionally if you think coroutines are "daunting"? No one uses C++ for it's "convenience" factor. We use it for the power and control it affords.

> What I was thinking of as a state machine with using std::future was a single function state machine, using switch (state) to the state specific dispatch of asynch ops using std::future, wait for completion then select next state.

Uh huh. What about error propagation and all the other very real issues I mentioned that you are just ignoring? Why not just let the compiler do all the work the way it was spec'ed and implemented?

reply