This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
sender-awaitable needs a deduction guideSection: 33.13.1 [exec.as.awaitable] Status: New Submitter: Eric Niebler Opened: 2026-03-19 Last modified: 2026-03-21
Priority: Not Prioritized
View other active issues in [exec.as.awaitable].
View all other issues in [exec.as.awaitable].
View all issues with New status.
Discussion:
33.13.1 [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 33.13.1 [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}.
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:
This wording is relative to N5032.
Modify 33.13.1 [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>; }