首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NRVO也适用于合作项目吗?

NRVO也适用于合作项目吗?
EN

Stack Overflow用户
提问于 2020-05-18 13:05:54
回答 4查看 358关注 0票数 5

在下面的示例中,NRVO (命名返回值优化)应用于每个这篇文章

代码语言:javascript
复制
std::string f1()
{
    std::string str;

    return str; // NVRO applies here!
}

然而,考虑:

代码语言:javascript
复制
task<std::string> f2()
{
    std::string str;

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

回答 4

Stack Overflow用户

回答已采纳

发布于 2022-06-06 05:57:35

您所链接的文章所定义的NRVO (甚至不创建一个临时的)对协同不起作用,因为作品取决于用户提供的coroutine承诺类型:co_return语句中的表达式被输入到诺言的return_value方法中,后者可以决定如何处理它。

然而,有一个相关的优化仍然可能是有用的。[class.copy.elision]/3说:

隐式可移动实体是自动存储持续时间的变量,它要么是非易失性对象,要么是对非易失性对象类型的rvalue引用。在以下副本初始化上下文中,在尝试复制操作之前首先考虑移动操作:

  • 如果返回(stmt.return)或co_­return (stmt.return.coroutine)语句中的表达式是一个(可能是括号大小的)id-表达式,该表达式将命名在最内部封闭函数或lambda表达式的主体或参数声明子句中声明的隐式可移动实体,或
  • ..。

首先执行重载解析,以选择要调用的副本或return_­value重载的构造函数,就好像表达式或操作数是rvalue一样。如果第一次重载解析失败或未执行,则再次执行重载解析,将表达式或操作数视为lvalue。

这意味着,如果您从coroutine中按名称返回局部变量,它将被移动,而不是复制(只要允诺类型支持此操作)。例如,尽管不可能复制std::unique_ptr<int>,但clang仍然接受以下内容

代码语言:javascript
复制
// Assume a coroutine task type called Task<T> whose associated promise has a
// return_value(T) method. The co_return here will successfully call that
// method.
Task<std::unique_ptr<int>> MakeInt() {
  auto result = std::make_unique<int>(17);
  co_return result;
}

因此,即使没有使用std::move,优化的“值被馈送到coroutine允诺作为rvalue引用”也适用。但是标准并没有说“甚至没有调用move构造函数”,也没有,因为这取决于如何处理它所给的表达式的承诺。

票数 1
EN

Stack Overflow用户

发布于 2020-05-18 13:07:14

我知道NRVO (名为返回值优化)是强制性的,因为C++17:

事实并非如此。NRVO仍然是一种优化。

未命名的返回值优化(RVO)是强制性的。

// NVRO在这里也有保障吗?

不,因为NRVO从来没有得到保证。

票数 6
EN

Stack Overflow用户

发布于 2020-05-18 13:25:56

为了完整起见,C++17中的保证省略只适用于直接从函数返回prvalue。返回命名变量只能在编译器喜欢的情况下接受省略。

至于您问题的实质,co_return值从来不受复制省略、保证或其他因素的影响。return关键字中返回值键的省略,并且coroutines不允许使用return。他们使用co_return,这是标准中的省略逻辑并不是。所以省略不适用。

之所以这样做,是因为合作机制是如何运作的。协同线是一个函数,其中包含一个承诺对象。这个允诺对象就是您如何将coroutine的co_return值(和其他状态)传递给coroutine函数返回的“未来”对象。

省略在正常函数中工作,因为调用约定要求调用方将返回值的存储传递给函数。因此,函数的实现可以选择只在该存储中构建对象,而不是构建单独的堆栈对象并将其复制到return上。

在合作机制中,回报值存在于承诺中,所以这是不可能的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61870280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档