Skip to content

Instantly share code, notes, and snippets.

Created July 20, 2018 03:19
What would you like to do?
template <typename T>
struct ValueReceiver {
virtual void value(T) = 0;
template <typename T>
struct ValueOrErrorReceiver : ValueReceiver<T> {
virtual void value(T) = 0;
virtual void error(std::exception_ptr) = 0;
// It is up to each Future implementation to decide when to return a Fallible or Infallible Future.
struct FallibleOrInfallibleFuture {};
template <typename T>
struct FallibleFuture {
virtual FallibleOrInfallibleFuture then(ValueOrErrorReceiver<T>*) = 0;
template <typename T>
struct InfallibleFuture : FallibleFuture<T> {
// Only calls value() on the receiver, never error().
FallibleOrInfallibleFuture then(ValueOrErrorReceiver<T>* receiver) final {
return then(static_cast<ValueReceiver<T>*>(receiver));
virtual FallibleOrInfallibleFuture then(ValueReceiver<T>*) = 0;
Copy link

In this case the InfallibleFuture is-a FallibleFuture in which case an infallible future has access to error() and could call error() but just won't.

This is exactly the pattern used in P1055. The difference is that we don't define InfallibleFuture because whether a sender calls error, or done or value is an implementation detail, just like it is here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment