2

So far as I know, if function is return by value, it would be considered as rvalue.

But while I want to pass function return value to move constructor as an argument, the move constructor is not called but copy constructor instead.

Here is my code:

#include <stdio.h>
#include <string.h> // strncmp
#include <vector>

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

class apple_t {
  public:
    apple_t( double data2 ) {
      data = &data2;
      cout<<"value constructor"<<endl;
    }
    apple_t( const apple_t& apple ) {
      data = apple.data;
      cout<<"copy constructor"<<endl;
    }
    apple_t( apple_t&& apple ) {
      data = apple.data;
      apple.data = nullptr;
      cout<<"move constructor"<<endl;
    }

    ~apple_t(){ cout<<"apple killed"<<endl;}
  public:
    double* data;
};


apple_t create_apple(){ apple_t apple(apple_t(40.7)); return apple; } 


int main(int argc, char** argv)
{
  apple_t apple1(20.5);
  apple_t apple2(apple1);
  apple_t apple3(move(apple1));// std::move produces an rvalue-reference
  apple_t apple4( create_apple() );
}

The output is as below:

value constructor
copy constructor
move constructor
value constructor
apple killed
apple killed
apple killed
apple killed

I expected in "apple_t apple4( create_apple() );", the move constructor should be called instead of normal constructor "apple_t( double data2 )".

Could anyone help me this?

cpplearner
  • 13,776
  • 2
  • 47
  • 72
Ted
  • 189
  • 1
  • 3
  • 13
  • Someone told me it is because the return value optimization for some compilers. – Ted Apr 13 '18 at 03:29
  • Confirmed, looks like RVO in all its glory. Looked into assembly of optimized Vc++ 2017 build, no attempts to move, construction in place – Severin Pappadeux Apr 13 '18 at 16:45

0 Answers0