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 typeX&
,const X&
,volatile X&
orconst 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.