class Class { public: Class& operator=(const Class&&) { return *this; } }; int main() { Class c1; Class c3(c1); return 0; } 

Why when adding to class

 Class& operator=(const Class&&) 

visual-studio-2017 writes:

E1776 "Class :: Class (const Class &)" function (declared implicitly) cannot be referenced because this function has been removed.

There should be a standard copy constructor.

2 answers 2

According to the current vision of this question, if the user explicitly provides any function from the Rule of Five (copy constructor, move constructor, copy assignment operator, move assignment operator, destructor), this should ideally lead to automatic suppression of the implicit generation of all other Rule Five functions.

However, for compatibility with existing code, i.e. with the "classic" C ++ 98 behavior, currently (in the C ++ 17 standard) this rule is only partially implemented, in the following "compromise" manner:

  1. Explicitly provided by the user functions from the "classic" Rule of Three (copy constructor, copying assignment operator, destructor) do not suppress the implicit generation of each other, but suppress the generation of the displacement constructor and the transfer assignment operator.
  2. The explicitly provided by the user "new" function from the Rule of Five (move constructor, moving assignment operator) suppresses the implicit generation of all other functions from the Rule of Five.

You explicitly provided a moving assignment operator in your code. This made point 2 work, and all other functions of the Rule of Five were removed. If you declared an assignment statement with a parameter of type const Class & , then the copy constructor would not disappear anywhere (according to item 1). But as soon as && appears in your code, you can no longer worry about compatibility with C ++ 98. (A separate question - why did you need such a strange type of parameter const Class && ? What did you try to achieve?)

The behavior described in clause 1 is obsolete and will be abolished in the future. That is, any explicitly provided Rule Five function will suppress the generation of all others. However, as soon as this happens - one can only guess.

  • [The behavior described in clause 1 is obsolete and will be eliminated in the future.] This will have a disastrous effect on the backward compatibility of billions of lines of code. Therefore, it is unlikely that it will be abolished. - pepsicoca1
  • @ pepsicoca1 Perhaps you are right. K & R function declarations are obsolescent from 89, but no one dared to remove them from C. On the other hand, narrowing conversions in {} in C ++ were boldly forbidden ... Converting a string literal to a non-constant pointer β€” too. Wait and see. - AnT
  • [K & R function declarations are obsolescent from 89] In my opinion, some of the currently working versions of Linux-Unix kernels still contain code written well before 89. Once I looked into the Linux header, and then there are variables up to the first bracket {. Therefore, do not clean. By the way, you can write a code analyzer tool that shows what percentage of obsolete structures are used in the code. To process this tool some large repository of code like sourceforge. If construction is used less than 1%, then remove from standard. If more, then leave. Scientific approach. - pepsicoca1

If there is at least one explicit copy / move constructor or corresponding assignment operator in the class, the others are not generated by the compiler.

  • Strange, previously generated. :-( - pepsicoca1