NRVO 是否也适用于协程?

Does NRVO also apply to coroutines?

在以下示例中,NRVO(名为 Return 值优化) 根据 this article:

适用
std::string f1()
{
    std::string str;

    return str; // NVRO applies here!
}

但是,请考虑:

task<std::string> f2()
{
    std::string str;

    co_return str; // Does NVRO also apply here?
}

I know that NRVO (Named Return Value Optimization) is mandatory since C++17:

不是。 NRVO仍然是一个优化。

非命名 Return 值优化 (RVO) 是必需的。

// Is NVRO also guaranteed here?

不,因为永远无法保证 NRVO。

为了完整性,C++17 中的保证省略仅适用于直接从函数中 returning 纯右值。返回一个命名变量只有在编译器喜欢的情况下才会被省略。

至于您问题的实质,co_return从不 受复制省略、保证或其他方式影响。 return 值的省略键关闭了 return 关键字,协程不允许使用 return。他们使用 co_return,而 elision logic in the standard doesn't key off of。所以省略不适用。

之所以这样做是因为协同程序的工作方式。协程是一个函数,其中包含一个 promise 对象。这个 promise 对象是你如何将协程的 co_return 值(和其他状态)传递给协程函数 returned.

的 "future" 对象

Elision 在普通函数中有效,因为调用约定要求调用者将 return 值的存储传递给函数。因此,该函数的实现可以选择只在该存储中构建对象,而不是构建一个单独的堆栈对象并在 return.

上复制到其中。

在协程中,return 值存在于 promise 中,所以这不可能真正发生。

只是因为答案看起来太长了。该标准表示语句 co_return <expr>; 等同于:

P.return_value(<expr>);

其中 P 是协程的 promise 对象。由此我想你可以回答这个问题和许多其他问题。

如果您正在寻找协程文档,请看这里: