Search code examples
c++c++11operator-overloadingmovemove-constructor

C++ move semantics: why copy assignment operator=(&) is called instead of move assignment operator=(&&)?


I have the following code:

#include <cstdio>
#include <iostream>

using std::cout;

struct SomeType {
  SomeType() {}

  SomeType(const SomeType &&other) {
    cout << "SomeType(SomeType&&)\n";
    *this = std::move(other);
  }

  void operator=(const SomeType &) {
    cout << "operator=(const SomeType&)\n";
  }

  void operator=(SomeType &&) {
    cout << "operator=(SomeType&&)\n";
  }
};

int main() {
  SomeType a;
  SomeType b(std::move(a));
  b = std::move(a);
  return 0;
}

I expect move constructor to call the move assignment operator. Here is the output of this program:

SomeType(SomeType&&)
operator=(const SomeType&)
operator=(SomeType&&)

As you can see, move assignment operator is successfully called, but not when assigning to *this inside move constructor. Why is this happening, can I fix it somehow?


Solution

  • Your move constructor takes a const SomeType&& rather than a SomeType&&. You cannot call a function that takes a SomeType&& (your move constructor) with a value of type const SomeType&&.

    Try making a move constructor that takes a SomeType&&.