Почему тип сопрограммы должен быть перемещаемым?

[Это относится к сопрограммам TS, VC ++ 17 и новее. Не дубликат ]

Я экспериментирую с экспериментальными сопрограммами. Я определил тип сопрограммы под названием «resumable_thing» (он основан на докладе Макнеллиса в 2016 году. В настоящее время он превратился в примитивный одноклеточный генератор.) Тип не скомпилируется, если не определен ни конструктор копирования, ни конструктор перемещения, несмотря на то, что ctor никогда не может быть вызван?

Это почему?

#include <iostream>
#include <experimental/coroutine>
#include <experimental/generator>

using namespace std;
using namespace experimental;
template<class T>
struct resumable_thing {
struct promise_type {
T _value;
resumable_thing get_return_object() {
return resumable_thing(coroutine_handle<promise_type>::from_promise(*this));
}
auto initial_suspend() { return suspend_always{}; }
auto final_suspend() { return suspend_always{}; }
void return_value(const T& value) {_value = value; }
void yield_value(const T&v) { return_value(v); }
};

coroutine_handle<promise_type> _coroutine;

// ???? Why must I define this? ????
resumable_thing(resumable_thing &&other) {
assert(false);
_coroutine = std::move(other._coroutine);
other._coroutine = nullptr;
}
// Member functions
void resume() { _coroutine.resume(); }
auto get() {return _coroutine.promise()._value;}
auto operator() () { resume(); return get(); }

// Ctors dtors
resumable_thing(resumable_thing const&) = delete;
resumable_thing& operator=(resumable_thing const&) = delete;
resumable_thing() = default;

explicit resumable_thing(coroutine_handle<promise_type> coroutine)
: _coroutine(coroutine)
{}

~resumable_thing() { if (_coroutine) _coroutine.destroy(); }};

static
resumable_thing<int> take_five() {
for (int i = 0; i<5 ; ++i) {
co_yield i;
}
co_return -1;
}

int main() {
auto count = take_five();
for (int i = count(); i >= 0; i=count()) {
cout << i << '\n';
}
return 0;
}

ДОБАВЛЕНО ПОЗЖЕ. Я до сих пор не знаю, почему VC ++ жалуется. В любом случае, ясно, что должны делать грузчики, если они что-то делают, а именно:

resumable_thing(resumable_thing &&right_)
: coroutine_(right_.coroutine_)
{
right_.coroutine_ = nullptr;
}

resumable_thing &operator=(resumable_thing &&right_)
{
if (this != std::addressof(right_)) {
coroutine_ = right_.coroutine_;
right_.coroutine_= nullptr;
}
return *this;
}

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]