Home > Net >  Why auto cannot be used to define an implicitly deleted constructor
Why auto cannot be used to define an implicitly deleted constructor

Time:11-22

I have this small snippet (compiled with g ) where I have defined a move constructor:

#include <iostream>
using namespace std;

class A {
public:
  A() = delete;
  A(int value) : value(value) {}
  void operator=(const auto &other) = delete;
  ~A() { cout << "Destructor called..." << endl; }

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

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

private:
  int value;
};

int main() {
  A p1(2);
  A p2(p1);

  return 0;
}

The problem is that I'm getting main.cpp:27:10: error: use of deleted function 'constexpr A::A(const A&)'

From what I understand, there is a compiler convention to implicitly delete any copy operations when a move constructor is defined. They will have to be explicitly defined if the user needs them.

However, I attempt to define a copy constructor using auto as the argument. If the constructor signature is A(const A &other) the program runs fine.

Since auto will be resolved to A, what is the reason for which the compiler still deems that particular constructor deleted?

CodePudding user response:

Since auto will be resolved to A, what is the reason for which the compiler still deems that particular constructor deleted?

Because A::A(const auto &) cannot be a copy constructor as when auto is used in the parameter of a function, that function declaration/definition is actually for a function template. Basically A::A(const auto&) is a templated constructor. But according to class.copy.ctor a templated constructor cannot be a copy constructor.

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments ([dcl.fct.default]).

(emphasis mine)


And since you've defined a move constructor A::A(const A&&), the synthesized copy ctor A::A(const A&) is implicitly deleted. But note that the implicitly deleted copy ctor A::A(const A&) takes part in overload resolution and is still a better match than the templated constructor A::A(const auto&). Thus, the copy ctor is chosen but since it is deleted(implicitly) we get the mentioned error.


  • Related