5

I have this piece of code. I was expecting d3 to be created with move constructor as well, as I passed a rvalue temporary.

#include <iostream>

using namespace std;

struct Data {
    Data(): x(1)
    {
        cout << "constructor" << endl;
    }

    Data(const Data& original): x(2)
    {
        cout << "copy constructor" << endl;
    }

    Data(Data&& original): x(3)
    {
        cout << "move constructor" << endl;
    }

    int x;
};

int main() {
    Data d1; // constructor
    cout << "d1:" << d1.x << endl << endl;

    Data d2(d1); // copy constructor
    cout << "d2:" << d2.x << endl << endl;

    Data d3(Data{}); // move constructor?
    cout << "d3:" << d3.x << endl << endl;

    Data d4(move(Data{})); // move constructor?
    cout << "d4:" << d4.x << endl << endl;

    return 0;
}

I saw output as:

constructor
d1:1

copy constructor
d2:2

constructor
d3:1

constructor
move constructor
d4:3

Although d4 is constructed with move constructor as I expected, I don't understand why d3.x got value 1. It seems d3 is constructed by the default constructor?

Yong Li
  • 607
  • 3
  • 15
  • BTW, traditional copy constructor use const reference instead of non-const reference. – Jarod42 Dec 24 '17 at 11:28
  • 2
    Worth nothing that the reason why this happens differs between C++11 and C++17. In C++11, it also may not happen. In C++17, it must happen. – StoryTeller - Unslander Monica Dec 24 '17 at 11:29
  • 2
    According to the answer in the duplicated question, this happens whenever a temporary object is created for the sole purpose of being copied and subsequently destroyed (copy-ellision). But this sounds exactly like the intended use case for move constructor? – Yong Li Dec 24 '17 at 11:31
  • 2
    But if the move constructor can be avoided entirely isn't this better ? – Richard Critten Dec 24 '17 at 11:33

0 Answers0