传递给协程的临时对象什么时候被销毁?

When do temporaries passed to coroutines get destroyed?

我对传递给协程任务的临时对象的生命周期感到困惑。考虑这个例子:

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

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

如果这些函数返回 void,那么传递给 UseObjectObject() 将在分号处销毁(即在 UseObject 完成后)。但是,我不确定是否同样适用于协程。通过引用将临时对象传递给例程是否安全?如果临时变量不在分号处,什么时候销毁它?

此外,作为健全性检查,这样写是否总是安全的:

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

因为 staying_alive 在 co_await 完成后销毁了?

这实际上是 open issue with the current draft 的主题。引用问题:

The intent is that copies/moves of parameters (if required) are created preserving the exact type (including references, r-references, etc). The wording in 11.4.4[dcl.fct.def.coroutine]/11 does not seem to express that clearly.

基于此,协程框架似乎将捕获对临时对象的引用。

因为 co_await 是一个表达式,临时变量应该在它出现的完整表达式的末尾被销毁。您上面的代码是否安全将取决于所涉及的两个协程的具体实现是否使 co_await 在调用 UseObject 时安全,并引用一个临时对象。具体来说,请注意 co_await 的作用取决于它所应用的表达式的类型以及它出现在其中的协程的承诺类型。此外,UseObject(我们不知道的定义) 至少在原则上,可以根据给定的参考做各种奇怪的事情……