Title
sender-awaitable needs a deduction guide
Status
new
Section
[exec.as.awaitable]
Submitter
Eric Niebler

Created on 2026-03-19.00:00:00 last changed 1 week ago

Messages

Date: 2026-03-21.14:52:28

Proposed resolution:

This wording is relative to N5032.

  1. Modify [exec.as.awaitable] as indicated:

    -2- The type sender-awaitable<Sndr, Promise> is equivalent to:

    namespace std::execution {
      template<class Sndr, class Promise>
      class sender-awaitable {
        struct unit {};                                             // exposition only
        using value-type =                                          // exposition only
          single-sender-value-type<Sndr, env_of_t<Promise>>;
        using result-type =                                         // exposition only
          conditional_t<is_void_v<value-type>, unit, value-type>;
        struct awaitable-receiver;                                  // exposition only
      
        variant<monostate, result-type, exception_ptr> result{};    // exposition only
        connect_result_t<Sndr, awaitable-receiver> state;           // exposition only
      
      public:
        sender-awaitable(Sndr&& sndr, Promise& p);
        static constexpr bool await_ready() noexcept { return false; }
        void await_suspend(coroutine_handle<Promise>) noexcept { start(state); }
        value-type await_resume();
      };
      
      template<class Sndr, class Promise>
        sender-awaitable(Sndr&&, Promise&) -> sender-awaitable<Sndr, Promise>;
    }
    
Date: 2026-03-19.00:00:00

[exec.as.awaitable] p2 has the following class declaration for the exposition-only sender-awaitable type:

template<class Sndr, class Promise>
class sender-awaitable {
  struct unit {};                                             // exposition only
  using value-type =                                          // exposition only
    single-sender-value-type<Sndr, env_of_t<Promise>>;
  using result-type =                                         // exposition only
    conditional_t<is_void_v<value-type>, unit, value-type>;
  struct awaitable-receiver;                                  // exposition only

  variant<monostate, result-type, exception_ptr> result{};    // exposition only
  connect_result_t<Sndr, awaitable-receiver> state;           // exposition only

public:
  sender-awaitable(Sndr&& sndr, Promise& p);
  static constexpr bool await_ready() noexcept { return false; }
  void await_suspend(coroutine_handle<Promise>) noexcept { start(state); }
  value-type await_resume();
};

In [exec.as.awaitable] p2, CTAD is used to deduce the template parameters of sender-awaitable in the expressions sender-awaitable{adapted-expr, p} and sender-awaitable{expr, p}.

If `decltype(expr)` is a type Expr& (i.e., `expr` is an lvalue subexpression), then CTAD will deduce the type as sender-awaitable<Expr, Promise> and the expression sender-awaitable{expr, p} will be ill-formed because it is trying to bind an lvalue subexpression to an rvalue reference parameter.

The intention was that the template parameter `Sndr` would be deduced preserving the cv- and reference-qualification of the sender subexpression. In order to achieve that, we need to add a deduction guide.

History
Date User Action Args
2026-03-21 14:52:28adminsetmessages: + msg16036
2026-03-19 00:00:00admincreate