Я экспериментирую с экспериментальными сопрограммами. Я определил тип сопрограммы под названием «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;
}
Задача ещё не решена.
Других решений пока нет …