Возобновление final_suspend вызывает ошибку, а не уничтожает сопрограмму

Джеймс МакНеллис в своей презентации «Введение в сопрограммы C ++» (https://youtu.be/ZTqHjjm86Bw?t=1898) говорит следующее:

Сопрограмма уничтожается, когда:

  • final_suspend возобновляется,
  • coroutine_handle<> :: destroy () вызывается,

что произойдет первым.

В моих тестах я вижу (VS 2015, VS 2017 RC), что возобновление сопрограммы, которая приостановлена ​​на final_suspend, вызывает ошибку:

Необработанное исключение в 0x010B9EDD в Awaits2017.exe: код инструментария RangeChecks обнаружил доступ к массиву вне диапазона. произошло

Есть идеи, что здесь может происходить?

#include <experimental/resumable>

using namespace std;
using namespace std::experimental;

struct Coro
{
coroutine_handle<> m_coro;
Coro(coroutine_handle<> coro) : m_coro(coro) {}

struct promise_type
{
Coro get_return_object()
{
return Coro(coroutine_handle<promise_type>::from_promise(*this));
}

auto initial_suspend() { return false; }
auto final_suspend() { return true; }
void return_void() {}
};
};

Coro simple()
{
co_return;
}

int main()
{
Coro c = simple();
c.m_coro.resume(); // runtime error here
}

1

Решение

Практическое правило:

  • Если final_suspend возвращается trueпозвони coroutine_handle<>::destroy(), вместо resume(),

  • Если final_suspend возвращается falseне стоит звонить destroy() также сопрограмма сама себя очистит.

Обратите внимание, что сопрограмма, включенная в VS 2015, — это не то, что Джеймс МакНеллис показал в видео (предложение имеет много ревизий), а описание:

final_suspend возобновлен

может быть запутанным Это на самом деле не значит resume() называется.

2

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

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

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