首页 > 解决方案 > RVO 和移动构造函数

问题描述

#include <bits/stdc++.h>

struct Row
{
  int a;
  Row() { puts("default"); }
  Row(const Row &other) { puts("copy"); }
  Row(Row &&other) { puts("move"); }
  Row(int) { puts("conv. c'tor"); }
};

Row return_row()
{

  Row r(6);
  Row second = r;
  return second; // move happens here
}

int main()
{
  Row x = return_row();
}

为什么它打印移动而不是复制,因为我正在复制左值?我已经关闭了 elide 构造函数标志,它仍然打印移动。是因为 RVO/NRVO 吗?如果是,有人可以解释在哪种情况下会发生 RVO/NRVO 吗?

标签: c++c++11

解决方案


[class.copy]/32当满足或将满足复制操作的省略标准时,除了源对象是函数参数,并且要复制的对象由左值指定,重载决议为首先执行选择复制的构造函数,就好像对象是由右值指定的一样。如果重载决议失败,或者如果所选构造函数的第一个参数的类型不是对对象类型的右值引用(可能是 cv 限定的),则再次执行重载决议,将对象视为左值。

该子句允许将局部变量或函数参数视为return语句中的右值,并从中移动构造返回值。


推荐阅读