RVO是否适用于这种情况?

时间:2016-12-03 17:20:45

标签: c++ c++11 rvo nrvo

我们说我们有这种情况

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

RVO是否适用于此?我认为答案是否定的,因为应用RVO的规则是:" 如果函数按值返回类类型,则return语句的表达式是非的名称具有自动存储持续时间的volatile对象,它不是函数参数,或者是catch子句参数,而具有与函数的返回类型相同的类型(忽略顶级cv资格),那么省略复制/移动 " 在这种情况下,返回的对象与函数的返回类型没有相同的类型,但我不是100%在这里不应用RVO。

非常感谢。

PS。在这次谈话中https://www.youtube.com/watch?v=AKtHxKJRwp4(第40分钟,第18章)来自Microsoft的Stephan讨论了无法应用RVO的情况,因为函数的返回类型与返回对象的类型不同(在他的示例中为元组与一对)。我认为同样的原则适用于此。

1 个答案:

答案 0 :(得分:5)

我认为您将NRVORVO混淆。

  • NRVO - 已命名返回值优化
  • RVO - (未命名)返回值优化

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

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

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

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

  

12.8 复制和移动班级对象 [ class.copy ]   ...   的 31   ...

     

- 当复制/移动尚未绑定到引用(12.2)的临时类对象时   对于具有相同cv-unqualified类型的类对象,可以省略复制/移动操作   将临时对象直接构造到省略的复制/移动

的目标中

通过返回char array构建一个临时std::string 将返回给调用者。