简体   繁体   中英

C++ move constructor called instead of copy constructor

I have this snippet of code which I'm compiling with g++.exe -std=c++20 :

#include <iostream>
using namespace std;

class A {
public:
  A() = delete;
  A(int value) : value(value) {}
  // A(auto &other) {
  //   cout << "Copy constructor called..." << endl;
  //   value = other.value;
  // }

  void operator=(const auto &other) = delete;

  A(auto &&other) {
    cout << "Move constructor called..." << endl;
    value = other.value;
  }

  ~A() { cout << "Destructor called..." << endl; }

  friend ostream &operator<<(ostream &os, const A &a);

private:
  int value;
};

ostream &operator<<(ostream &os, const A &a) {
  os << a.value;
  return os;
}

int main() {
  A p1(2);
  cout << "p1: " << p1 << endl;
  A p2(p1);

  cout << "p2: " << p2 << " p1: " << p1 << endl;

  return 0;
}

The problem I'm having is that when the copy constructor is commented the output is

Move constructor called...
p2: 2 p1: 2
Destructor called...
Destructor called...

And if I uncomment the copy constructor, the output becomes

p1: 2
Copy constructor called...
p2: 2 p1: 2
Destructor called...
Destructor called...

I am wondering why doesn't the compiler just call a default copy constructor (what happens when I delete the move constructor or change its argument to const , so it doesn't match the call).

In this case it's not actually a move constructor, it's a constructor with a universal reference , so it takes both lvalues and rvalues. If you want to restrict it to rvalues only, you should use explicit type:

A(A &&other) {
  ...
}

I am wondering why doesn't the compiler just call a default copy constructor (what happens when I delete the move constructor or change its argument to const , so it doesn't match the call).

Be advised that this won't happen, because copy operations are implicitly deleted if you explicitly add any move operation, so you will have to add it explicitly in this case:

A(const A &other) = default;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM