2016-12-03 125 views
7

比方说,我们有这种情况RVO是否适用于这种情况?

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

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

非常感谢。

PS。在这次演讲中https://www.youtube.com/watch?v=AKtHxKJRwp4(分钟40,第18次)来自微软的Stephan谈到了RVO无法应用的情况,因为函数的返回类型与返回对象的类型不同(在他的例子中是一个元组与一对)。我认为这里适用同样的原则。

+3

它大部分等价于'return std :: string(“name”)'...... – Jarod42

+0

返回的结果是* not * const char *'... – user268396

+0

@ user268396你是对的,但是在大多数情况下案例(也在这里)它被隐式转换为一个之前转换为字符串... :) –

回答

5

我觉得你很困惑NRVORVO

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

NRVO涉及命名的变量,而RVO包括那些在return声明构造无名的临时。

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

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

按照C++11标准我看不出有什么理由不能发生RVO

12.8复制和移动类对象[ class.copy ] ... ...

- 当一个临时类对象还没有出现d参考(12。2)将被复制/移动 用相同的CV-非限定类型的一类对象中,复制/移动操作可以通过 直接构建临时物体插入省略副本的目标可以省略/移动

通过返回char array构造了一个临时std::string,并且是返回给调用者的东西。

3

NRVO和RVO是elision的不同情况。

Elision是将多个对象的生命周期合并为一个对象的地方。

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

省音被允许在该return行,函数的返回值创建的临时之间你的榜样,并命名变量你存储在返回值。每一个严肃的编译器可以和会的Elid这些值加在一起,除非你明确地告诉它不要通过编译器标志。而在C++ 17中,这些选择将是强制性的。

相关问题