4201. with-await-transform::await_transform should not use a deduced return type

Section: 33.9.4 [exec.awaitable] Status: Tentatively Ready Submitter: Brian Bi Opened: 2025-02-03 Last modified: 2025-02-07

Priority: Not Prioritized

View all issues with Tentatively Ready status.

Discussion:

Imported from cplusplus/sender-receiver #309.

33.9.4 [exec.awaitable]/p5

The use of the deduced return type causes the definition of the sender's as_awaitable method to be instantiated too early, e.g., when the sender is passed to get_completion_signatures.

[Eric provides wording]

[2025-02-07; Reflector poll]

Set status to Tentatively Ready after five votes in favour during reflector poll.

Proposed resolution:

This wording is relative to N5001.

  1. Modify 33.9.4 [exec.awaitable] as indicated:
    -5- Let with-await-transform be the exposition-only class template:
    
    namespace std::execution {
      template<class T, class Promise>
        concept has-as-awaitable =                                  // exposition only
          requires (T&& t, Promise& p) {
            { std::forward<T>(t).as_awaitable(p) } -> is-awaitable<Promise&>;
          };
    
      template<class Derived>
        struct with-await-transform {                               // exposition only
          template<class T>
            T&& await_transform(T&& value) noexcept {
              return std::forward<T>(value);
            }
    
          template<has-as-awaitable<Derived> T>
            decltype(auto)auto await_transform(T&& value)
              noexcept(noexcept(std::forward<T>(value).as_awaitable(declval<Derived&>())))
            -> decltype(std::forward<T>(value).as_awaitable(declval<Derived&>())) {
              return std::forward<T>(value).as_awaitable(static_cast<Derived&>(*this));
            }
        };
    }