Джеймс МакНеллис в своей презентации «Введение в сопрограммы C ++» (https://youtu.be/ZTqHjjm86Bw?t=1898) говорит следующее:
Сопрограмма уничтожается, когда:
что произойдет первым.
В моих тестах я вижу (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
}
Практическое правило:
Если final_suspend
возвращается true
позвони coroutine_handle<>::destroy()
, вместо resume()
,
Если final_suspend
возвращается false
не стоит звонить destroy()
также сопрограмма сама себя очистит.
Обратите внимание, что сопрограмма, включенная в VS 2015, — это не то, что Джеймс МакНеллис показал в видео (предложение имеет много ревизий), а описание:
final_suspend возобновлен
может быть запутанным Это на самом деле не значит resume()
называется.
Других решений пока нет …