Skip to content

Conversation

@ericniebler
Copy link
Collaborator

@ericniebler ericniebler commented Dec 3, 2025

ATTN: this PR drops support for senders with static member functions for connect and get_completion_signatures.

problem

in stdexec today, many of the senders have non-conforming connect and get_completion_signatures member functions. that's because stdexec must support C++20, which does not have C++23's "deducing this" feature.

instead, stdexec::connect has a non-conforming extension where it looks for a static member function connect, like:

template <class Self, class Receiver>
static auto connect(Self&& self, Receiver rcvr) -> opstate_t<Self, Receiver>;

that is a problem because it would prevent senders from stdexec from being used with third party algorithms that are not hip to this subterfuge.

but defining connect with overloads like below comes with its own difficulties:

template <class Receiver>
auto connect(Receiver rcvr) && -> opstate_t<self_t, Receiver>;

template <class Receiver>
auto connect(Receiver rcvr) const & -> opstate_t<self_t const&, Receiver>;

if opstate_t is some metafunction that computes an opstate type, now the compiler must compute the type twice to perform overload resolution. that's more expensive, and can even cause hard failures when things aren't properly constrained.

solution

this pr introduces a portability macro for C++23's deducing this feature. it can be used as follows:

template <class Self, class Receiver>
STDEXEC_EXPLICIT_THIS_BEGIN(auto connect)(this Self&& self, Receiver rcvr)
  -> opstate_t<Self, Receiver>;

STDEXEC_EXPLICIT_THIS_END(connect)

in C++23, this expands simply into:

template <class Self, class Receiver>
auto connect(this Self&& self, Receiver rcvr)
  -> opstate_t<Self, Receiver>;

but in C++20 is expands to:

template <class Self, class Receiver>
static auto static_connect(Self&& self, Receiver rcvr)
  -> opstate_t<Self, Receiver>;

template <class... Ts>
auto connect(Ts&&... ts) &&
  -> decltype(static_connect(std::move(*this), std::forward<Ts>(ts)...)) {
  return static_connect(std::move(*this), std::forward<Ts>(ts)...);
}

template <class... Ts>
auto connect(Ts&&... ts) const &
  -> decltype(static_connect(*this, std::forward<Ts>(ts)...)) {
  return static_connect(*this, std::forward<Ts>(ts)...);
}

now the sender has conforming signatures for connect. behind the scenes, stdexec::connect checks first for a static static_connect member and uses that if it finds one. otherwise, it calls the connect member function.

@ericniebler ericniebler force-pushed the use-explicit-this-portability-macro branch 2 times, most recently from d7c9709 to dd91a0f Compare December 9, 2025 20:46
@ericniebler ericniebler changed the title [WIP] make senders conforming by giving them non-static connect and get_completion_signatures member fns make senders conforming by giving them non-static connect and get_completion_signatures member fns Dec 10, 2025
@ericniebler ericniebler marked this pull request as ready for review December 10, 2025 00:37
@ericniebler ericniebler force-pushed the use-explicit-this-portability-macro branch from 7e3acda to 72292a1 Compare December 10, 2025 19:33
@ericniebler ericniebler force-pushed the use-explicit-this-portability-macro branch from 72292a1 to 1acd3eb Compare December 11, 2025 22:42
@copy-pr-bot
Copy link

copy-pr-bot bot commented Dec 11, 2025

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@ericniebler
Copy link
Collaborator Author

/ok to test 1acd3eb

@ericniebler ericniebler merged commit 35a8de8 into NVIDIA:main Dec 11, 2025
21 checks passed
@ericniebler ericniebler deleted the use-explicit-this-portability-macro branch December 11, 2025 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant