这是indexloc提供的服务,不要输入任何密码
Skip to content

Why Can't OperationState be Move-Only? #1588

@lixin-wei

Description

@lixin-wei

Hi everyone, I want to make a one-shot move-only sender, so I make connect() only applies to rvalue by adding && after, which is fine.

template <class Receiver>
Operation<Receiver> connect(Receiver&& receiver) && noexcept {
  return Operation(std::move(receiver));
}

Then, intutively, I also make OperationState move-only, because I want it to be started only once.

void start() && noexcept {
    receiver.set_value("hello");
}

But it won't compile, the error says it doesn't satisfies the OperationState concept.

/opt/compiler-explorer/libs/stdexec/trunk/include/stdexec/__detail/__operation_states.hpp:63:29:   in requirements with '_Op& __op' [with _Op = MySender::Operation<stdexec::__sync_wait::__receiver<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::__t>]
/opt/compiler-explorer/libs/stdexec/trunk/include/stdexec/__detail/__operation_states.hpp:63:65: note: the required expression 'stdexec::start(__op)' is invalid
   63 |                          && requires(_Op &__op) { stdexec::start(__op); };
      |                                                   ~~~~~~~~~~~~~~^~~~~~

if I remove the && after start(), it will compile.

So Why Can't OperationState be move-only? Could anyone help me? Thanks in advance!

Full code

compiler explorer: https://godbolt.org/z/n58T9Mv45

#include <string>
#include "stdexec/__detail/__execution_fwd.hpp"
#include "stdexec/__detail/__sync_wait.hpp"

struct MySender : stdexec::sender_t {
  using completion_signatures = stdexec::completion_signatures<stdexec::set_value_t(std::string)>;

  template <class Receiver>
  struct Operation {
    Receiver receiver;
    
    
    void start() && noexcept { // <- Pay attention to the '&&' here
                           // if I remove it, it will compile
        receiver.set_value("hello");
    }
  };

  template <class Receiver>
  Operation<Receiver> connect(Receiver&& receiver) && noexcept {
    return Operation(std::move(receiver));
  }
};

int main() { stdexec::sync_wait(MySender()); }

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