[cfe-dev] Move constructor forces copy assignment to be implicitly defaulted?
Steve Ramsey
clang at lucena.com
Mon May 28 16:04:52 PDT 2012
On May 29, 2012, at 1:56 AM, Suman Kar (from the future) wrote:
> A quick question:
>
> struct A {};
>
> struct B : A { ~B() {} };
>
> A makeA() {
> A a;
> return a;
> }
>
> B makeB() {
> B b;
> return b;
> }
>
> int main() {
> A a = makeA();
> B b = makeB();
> }
>
> Is it correct to assume that A will be moved and B will not? Should a
> diagnostic be required for the call to makeB?
I’m real glad you asked that. This plays into 12.8 p7 from the FDIS:
> If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.
This paragraph features in my nightmares. I go back every few weeks and try and parse it again, but I still get confused. In my current interpretation, it’s saying that a copy constructor will always be declared, whether implicitly or explicitly; any implicitly declared copy constructor will always be defined as deleted unless there are no implicitly or explicitly declared move special member functions.
“But, wait,” you’re thinking, “didn’t I ask about the move constructor?” Well, yes. B’s move constructor will not be declared at all because of the presence of a user-declared destructor, and hence will not be defined. However, B is still technically move-constructible because it will fall back to the implicitly defined copy constructor (as per the previously mentioned Note in 12.8 p9), and that copy constructor exists because of 12.8 p7.
Steve
More information about the cfe-dev
mailing list