I want to overload a common copy-assignment operator normally. At first I used a interface that only requires a const reference to the source, and explicitly disabled the interface that accepts a modifiable reference, but I can not pass the compilation. The compiler reports "error: use of deleted function ‘ClassA& ClassA::operator=(ClassA&)"
Of course, I can get compiled if I don't expicitly delete the interface, but that is not my purpose. I'd like to explicitly delete it, to avoid unexpected using it.
Why a copy-assignment operation needs a modifiable reference to the source, instead of a const reference? The assignment operation just needs to access the source read-only!
There is a same question about the copy-constructor, I omit it for simplifying.
What's wrong with my code? or we can NOT delete it?
My sample code is following:
class ClassA {
public:
ClassA() = default;
ClassA( ClassA & ) = default;
ClassA & operator=( ClassA & )
= delete // Must comment-out this, or we can't pass the compilation.
// { cout << "ClassA & operator=( ClassA & ) executed." << endl; return *this; }
;
ClassA & operator=( ClassA && ) {
cout << "ClassA & operator=( ClassA && ) executed." << endl;
return *this;
};
ClassA & operator=( const ClassA & ) {
cout << "ClassA & operator=( const ClassA & ) executed." << endl;
return *this;
};
ClassA & operator=( const ClassA && ) {
cout << "ClassA & operator=( const ClassA && ) executed." << endl;
return *this;
};
};
int main() {
ClassA oa, ob;
ob = oa;
return EXIT_SUCCESS;
};
or we can NOT delete it?
You just don't need to do that. If you provide a user-defined copy assignment operator, then no other ones will be implicitly-declared, i.e. only the user-defined one will exist.
If you do that, the copy assignment operator you explicitly marked as delete
will participate in overload resolution; when it's selected the compilation fails. For ob = oa;
, the operator=( ClassA & )
is a better match, if it doesn't exist, operator=( const ClassA & )
will be used and work fine.
So in this case you can just do
class ClassA {
public:
ClassA & operator=( ClassA && ) {
cout << "ClassA & operator=( ClassA && ) executed." << endl;
return *this;
}
ClassA & operator=( const ClassA & ) {
cout << "ClassA & operator=( const ClassA & ) executed." << endl;
return *this;
}
};