[dcl.fct.def.coroutine] p3 :
Тип обещания сопрограммы равен std::coroutine_traits<R, P1, ..., Pn>::promise_type
, где R
является типом возвращаемого значения функции, а P1 ... Pn
является последовательностью типов параметров функции, предшествует тип неявного параметра объекта (12.4.1), если сопрограмма не является статической c функция-член.
Неявный параметр объекта в вашем примере является константной ссылкой, и, следовательно, эта ссылка будет зависать при возобновлении выполнения после уничтожения объекта закрытия.
Однако, на заметку об объектах, уничтожаемых во время выполнения функции-члена, это действительно хорошо само по себе, и никто, кроме самого стандарта, не подразумевает этого в [basic] :
До начала срока службы объекта, но после того, как было выделено хранилище, которое будет занимать объект, или после того, как истек срок службы объекта и до того, как хранилище, которое занимал объект, используется повторно или освобождается любой указатель, который представляет адрес места хранения, где объект будет или был расположен, может использоваться, но только ограниченным образом. [...]
void B::mutate() {
new (this) D2; // reuses storage --- ends the lifetime of *this
f(); // undefined behavior
... = this; // OK, this points to valid memory
}
(Примечание: вышеуказанный UB объясняется тем, что неявное this
не стирается и по-прежнему ссылается на параметр неявного объекта.)
Таким образом, ваш пример выглядит четко определенным, при условии, что возобновление выполнения не подпадает под те же правила, что и исходный вызов. Обратите внимание, что ссылка на объект замыкания может быть висящей, но между приостановкой и возобновлением к ней нет доступа.