0
#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();
}

Why it prints move instead of copy since I am copying lvalue? I have turned of elide constructors flag still it prints move. Is it because of RVO/ NRVO ? If it is, can someone explain in which scenario RVO/NRVO happens?

cigien
  • 57,834
  • 11
  • 73
  • 112
Vegeta
  • 461
  • 2
  • 6
  • In particular, this answer https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization/12953150#12953150 The first example there is the same as in your question. – cigien Dec 21 '20 at 11:11

1 Answers1

0

[class.copy]/32 When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload resolution fails, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue.

This clause allows a local variable or a function parameter to be treated as an rvalue in the return statement, and move-construct the return value from it.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85