1

I am experimenting with the following code :

#include <iostream>
#include <utility>
using namespace std;

class A
{
    int data;
public:
   A(): data{0}
   {

   }

   A(const A& other)
   {
       print(other);
   }


   A(A&& other)
   {
       print(other);
   }

   void print(const A& other) const
   {
      cout << "In print 1" << endl;
   }

   void print(const A&& other) const
   {
      cout << "In print 2" << endl;
   }

};


int main() {
    A a0;
    A a1(a0);
    A a2(A());

    return 0;
}

I was expecting the output to be :

In print 1
In print 1

However, the actual output is :

In print 1

Clearly, the move constructor is not getting called. Why so? And what is getting called in its place during construction of a2?

johngreen
  • 2,676
  • 5
  • 32
  • 47
  • A a3(std::move(a0)) – Build Succeeded Jan 20 '20 at 10:22
  • If you are in C++17 then you won't observe move- (or copy-) construction in `A a2(A{});` or `A a2 = A();` - all of these will just initialize `a2` using `A`'s default constructor. No temporary is created, copied, moved or assigned. – Max Langhof Jan 20 '20 at 12:21

1 Answers1

3

Because A a2(A()); is actually function declaration, not a declaration of an object. See this:

My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?

If you want to see the move constructor, do something like this:

A a2((std::move(A())));
artm
  • 17,291
  • 6
  • 38
  • 54
  • Or `A a2(A{});` (if move constructor is not elided). – Jarod42 Jan 20 '20 at 11:04
  • 1
    Note that neither `A a2 = A();` nor `A a2(A{});` (nor something like `A a2 = A(A(A()));` call the move constructor in C++17. The temporary is never materialized. See https://timsong-cpp.github.io/cppwp/n4659/dcl.init#17.6.1. – Max Langhof Jan 20 '20 at 12:18