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?

6
  • 3
    coliru.stacked-crooked.com/a/7f5cf2b59b260c3a Commented Oct 29, 2014 at 5:13
  • @P0W Ha, I was JUST about to post the exact same thing. Commented Oct 29, 2014 at 5:15
  • 1
    Suggested Reading : What are copy elision and return value optimization? Commented Oct 29, 2014 at 5:15
  • @P0W What did you actually do? Could you explain? Commented Oct 29, 2014 at 5:15
  • @DmitryFucintv What you're seeing is an optimization technique used my modern compilers Copy Elision. Please go through above link Commented Oct 29, 2014 at 5:17

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Could you clarify why the example coliru.stacked-crooked.com/a/7f5cf2b59b260c3a calls move contructor two times?
@DmitryFucintv d is moved from the rvalue f(1) (which was in turn moved from Y()), notice the post says move "twice"