Issue
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?
Solution
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.
Answered By - Jason Liam Answer Checked By - Mildred Charles (WPSolving Admin)