我们说我们有这种情况
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的情况,因为函数的返回类型与返回对象的类型不同(在他的示例中为元组与一对)。我认为同样的原则适用于此。
答案 0 :(得分:5)
我认为您将NRVO
与RVO
混淆。
NRVO
- 已命名返回值优化RVO
- (未命名)返回值优化 NRVO
涉及一个命名变量,而RVO
涉及在return
语句中构造的未命名临时变量。
视频上的示例是NRVO
,当类型不同时,命名对象显然不能在调用者堆栈上构建,因为它有在函数的堆栈中存在一个类型的一个对象,在调用者的堆栈中存在另一个类型的另一个对象。
您的示例是RVO
,您没有使用预先构造的命名对象。在您的代码中,您构建 临时对象作为返回值。因为它是临时,所引用的规则不适用。
根据C++11
标准,我看不出RVO
无法发生的原因:
12.8 复制和移动班级对象 [ class.copy ] ... 的 31 强> ...
- 当复制/移动尚未绑定到引用(12.2)的临时类对象时 对于具有相同cv-unqualified类型的类对象,可以省略复制/移动操作 将临时对象直接构造到省略的复制/移动
的目标中
通过返回char array
构建一个临时std::string
并 将返回给调用者。