0

The Standard provides an example regarding to the a move constructor. There is what it says:

A non-template constructor for class X is a move constructor if its first parameter is of type X&&, const X&&, volatile X&&, or const volatile X&&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).

I was trying to run some an experiments with an example the Stadard provides:

#include <iostream>
#include <limits>


struct Y {
    Y(){ std::cout << "Y()" << std::endl; };
    Y(const Y&){ std::cout << "Y(const Y&)" << std::endl; };
    Y(Y&&){ std::cout << "Y(const Y&&)" << std::endl; };
};

Y f(int)
{
    return Y();
}

Y d(f(1)); // calls Y(Y&&)
Y e = d; // calls Y(const Y&)

int main(){ }

DEMO

But instead copy constructor was called. Why that?

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 3
    http://coliru.stacked-crooked.com/a/7f5cf2b59b260c3a – P0W Oct 29 '14 at 05:13
  • @P0W Ha, I was JUST about to post the exact same thing. – chbaker0 Oct 29 '14 at 05:15
  • 1
    Suggested Reading : [_What are copy elision and return value optimization?_](http://stackoverflow.com/q/12953127/1870232) – P0W Oct 29 '14 at 05:15
  • @P0W What did you actually do? Could you explain? –  Oct 29 '14 at 05:15
  • @DmitryFucintv What you're seeing is an optimization technique used my modern compilers _Copy Elision_. Please go through above link – P0W Oct 29 '14 at 05:17
  • @P0W Ah, you've just added a flag no-elide-constructor. I forgot about copy-elision, thank you. –  Oct 29 '14 at 05:19

1 Answers1

2

The copy-constructor is invoked by the line:

Y e = d;

This cannot be a move operation , because d is an lvalue. This is why you see the copy constructor call in your output.

For the line Y d(f(1)), d is moved from the rvalue f(1) (which was in turn moved from Y()), however copy elision means that the output of both of these move-constructors may be suppressed.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • Could you clarify why the example coliru.stacked-crooked.com/a/7f5cf2b59b260c3a calls move contructor two times? –  Oct 29 '14 at 05:22
  • @DmitryFucintv _`d` is moved from the rvalue `f(1)` (which was in turn moved from `Y())`_, notice the post says _move_ "twice" – P0W Oct 29 '14 at 05:27