Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 295
yeputons Avatar asked Nov 14 '13 14:11

yeputons


Video Answer


2 Answers

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&&.

like image 83
Eric Finn Avatar answered Oct 19 '22 00:10

Eric Finn


std::move casts to an r-value reference. So it casts other to const SomeType &&. This of course cannot bind to SomeType &&, so it falls back to const SomeType &.

Remove the const from the move constructor's parameter.

like image 27
Angew is no longer proud of SO Avatar answered Oct 19 '22 00:10

Angew is no longer proud of SO