Skip to content

_sender-awaitable_ needs a deduction guide #354

Description

@ericniebler

[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.

Proposed Resolution

In [exec.as.awaitable]/p2, change the definition of sender-awaitable as follows:

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>;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions