[cfe-dev] Move constructor forces copy assignment to be implicitly defaulted?

Steve Ramsey clang at lucena.com
Mon May 28 12:58:59 PDT 2012

On May 28, 2012, at 11:32 AM, Howard Hinnant wrote:
> On May 28, 2012, at 2:15 PM, Steve Ramsey wrote:
>> In the second A, ignoring deprecated behavior, the move special member functions are implicitly declared and implicitly defined as deleted due to the presence of the explicitly declared copy special member functions.
> Wrong.  12.8 [class.copy]/p9:
>> 9 If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
>> * X does not have a user-declared copy constructor,
>> ...
> A has a user-declared copy constructor therefore the compiler will not implicitly declare a move constructor (and ditto for the move assignment operator).

Ah, absolutely correct. I had the outcome right, but my reasoning was wrong. Since the move functions are never declared, they’re never deleted; they simply don’t exist.

>> When make returns, it’s still not using the move constructor, but is allowed to use the copy constructor as a fallback behavior (though presumably not the return value optimization).
> The compiler isn't using A's move constructor because A doesn't have one.  However your conclusion is correct:  The compiler uses A's copy constructor.

Yes, I could have worded that better.

>> This is because B has implicitly defined special member functions,
> B has special copy members, but not special move members.
> B doesn't have an implicit move constructor because if it did it would be implicitly deleted (p9) because it would call A's deleted move constructor (p11).

Right, I should have been specific about which special member functions are defined.

>> and so when it goes to return b in MakeB, it calls its own move constructor as well as A’s default constructor, bypassing the move prohibition entirely.
> When B returns its copy constructor is used because there is no move constructor.

heh...and I finished with a typo. I actually did mean to type “copy constructor” there instead of “move constructor”. As per the Note in 12.8 p9:

> When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor.

Well, I suppose this was instructive, just not in the way that I’d hoped.


More information about the cfe-dev mailing list