Когда временные сигналы, передаваемые сопрограммам, уничтожаются? - PullRequest
13 голосов
/ 28 марта 2019

Я запутался в жизни временников, переданных на сопрограммы. Рассмотрим этот пример:

cppcoro::task<> UseObject(Object const& object);

cppcoro::task<> CallUseObject() {
    co_await UseObject(Object()); // is this valid?
}

Если бы это были функции, возвращающие void, то Object(), переданный UseObject, будет уничтожен в точке с запятой (т.е. после завершения UseObject). Однако я не уверен, относится ли это к сопрограммам. Безопасно ли передавать временное в рутину по ссылке? Когда временные уничтожаются, если это не точка с запятой?

Кроме того, для проверки работоспособности всегда можно написать:

cppcoro::task<> CallUseObject() {
    Object stayingalive;
    co_await UseObject(stayingalive);
}

поскольку staying_alive уничтожается после того, как co_await завершает работу?

1 Ответ

11 голосов
/ 28 марта 2019

На самом деле это тема открытого выпуска с текущим черновиком .Чтобы процитировать проблему:

Намерение состоит в том, что копии / перемещения параметров (если требуется) создаются с сохранением точного типа (включая ссылки, r-ссылки и т. Д.).Формулировка в 11.4.4 [dcl.fct.def.coroutine] / 11, кажется, не выражает это ясно.

Исходя из этого, может показаться, что кадр сопрограммы будет захватывать ссылку навременное.

Поскольку co_await является выражением, временное должно быть уничтожено в конце полного выражения, в котором оно появляется.Является ли ваш код выше безопасным или нет, будет зависеть от того, делает ли конкретная реализация двух сопрограмм безопасным co_await при вызове UseObject со ссылкой на временный.В частности, обратите внимание, что то, что делает co_await, зависит как от типа выражения, к которому он применяется, так и от типа обещания сопрограммы, в которой он появляется. Кроме того, UseObject (определение которого мы не знаем)мог бы, по крайней мере, в принципе, делать всякие странные вещи со ссылкой, которую он дал ...

...