c++move-constructor

C++ move constructor not called


In the following (borrowed) example, in my environment the move constructor is never called:

#include <iostream>

class MyClass {
  public:
      MyClass()
      {
          std::cout << "default constructor\n";
      }
      MyClass(MyClass& a)
      {
          std::cout << "copy constructor\n";
      }

      MyClass(MyClass&& b)
      {
          std::cout << "move constructor\n";
      } 
};  

void test(MyClass&& temp)
{
    MyClass a(MyClass{}); // calls MOVE constructor as expected
    MyClass b(temp); // calls COPY constructor...  
}

int main()
{
    test(MyClass{});
    return 0;
}

My output is: default constructor default constructor copy constructor

I use XCode version 9.1, shouldnt the move constructor be called on rvalue references? What am I missing here?

John.


Solution

  • What am I missing here?

    The point is that everything that has a name is lvalue.

    It means that named rvalue reference itself is lvalue and temp from:

    void test(MyClass&& temp)
    

    is lvalue as well. So move constructor is not called.

    If you want a move constructor to be called, use std::move:

    void test(MyClass&& temp)
    {
        // ...
        MyClass b(std::move(temp)); // use std::move here 
    }
    

    By the way,

     MyClass(MyClass& a)
     {
         std::cout << "copy constructor\n";
     }
    

    is not a copy constructor because copy constructor has a form of:

    MyClass(const MyClass& a) { ... }