RVO是否适用于这种情况?

Is RVO applied on this situation?

假设我们有这种情况

std::string v_1()
{
    return "name";
}
std::string test = v_1();

这里应用RVO了吗?我认为答案是否定的,因为应用 RVO 的规则之一是:“如果一个函数 return 是一个 class 类型的值,并且 return 语句的表达式是具有自动存储持续时间的非易失性对象的名称,它不是函数参数,也不是 catch 子句参数,并且 与return 类型的函数,则省略 copy/move" 在这种情况下,对象 returned 与函数的 return 类型不具有相同类型,但我不是 100% 认为 RVO 未在此处应用。

非常感谢。

PS。在本次演讲中 https://www.youtube.com/watch?v=AKtHxKJRwp4(第 40 分钟,第 18 秒)来自 Microsoft 的 Stephan 谈到了无法应用 RVO 的情况,因为函数的 return 类型与 returned 对象(在他的示例中是一个元组与一对)。我认为同样的原则也适用于此。

我认为您混淆了 NRVORVO

  • NRVO - 命名 return 价值优化
  • RVO - (未命名)return 价值优化

NRVO 涉及命名变量,而 RVO 涉及在 return 语句中构造的未命名临时变量。

视频中的示例是 NRVO,其中 命名对象 显然不能在 调用程序堆栈 上构建当类型不同时,因为函数堆栈中必须存在一种类型的一个对象,而调用者堆栈中必须存在另一种类型的另一个对象。

您的示例是 RVO,您没有使用预先构建的命名对象。在您的代码中,您正在 构造 一个 临时 对象作为 return 值。因为它是 临时 你引用的规则不适用。

根据 C++11 标准,我看不出 RVO 不能发生的原因:

12.8 Copying and moving class objects [ class.copy ] ... 31 ...

-- when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move

通过 return 构建一个 char array 一个临时的 std::string 并且 就是 returned 到来电者。

NRVO 和 RVO 是省略的不同情况。

省略是将多个对象的生命周期合并到一个对象中。

名称 NRVO 和 RVO 是编译器在标准允许时如何进行省略的名称。

在您的示例中,在 return 行上创建的临时变量、函数的 return 值和存储 return 值的命名变量之间允许省略。每个严肃的编译器都可以并且将会一起删除这些值,除非您明确告诉它不要通过编译器标志。在 C++17 中,这些省略将是强制性的。