4

I can have declaration of three constructors like

  • copy constructor C::C(const C&)
  • move constructor C::C(C&&)
  • C::C(const C&&)

in a class without ambiguity.

What do we call a constructor like C::C(const C&&)? Does it have some kind of nickname?

I can come up with =delete to explicitly prohibit users from unknowingly trying to move from const and restricting the automatic copy fallback effect. This reminds users what they are doing.

And is there any other use of it?

Praetorian
  • 106,671
  • 19
  • 240
  • 328
sandthorn
  • 2,770
  • 1
  • 15
  • 59
  • 1
    This signature also qualifies for the name "move constructor". – Ben Voigt Oct 03 '17 at 16:55
  • It is valid syntax but is useless as you can't move from a const object – NathanOliver Oct 03 '17 at 16:56
  • 1
    https://stackoverflow.com/a/28595415/1460794 – wally Oct 03 '17 at 16:57
  • Why is it wrong if the user of your class tries to move from a `const` object? – KABoissonneault Oct 03 '17 at 17:00
  • @KABoissonneault user can try - he will not succeed. To move from means to modify the object. You cannot modify const object – Artemy Vysotsky Oct 03 '17 at 17:07
  • @ArtemyVysotsky Yeah, is that a problem for this object? – KABoissonneault Oct 03 '17 at 17:08
  • @KABoissonneault When `C::C(const C&&)` is not declared, `C(std::move(aConstCObj))` matches the copy constructor "automatically silently". So users might be thinking they benefit from move semantics, which is not true. [wandbox.org/permlink/pLJk6HrG2DofpTrh](https://wandbox.org/permlink/pLJk6HrG2DofpTrh) – sandthorn Oct 03 '17 at 17:45
  • 1
    @sandthorn Does your client care? The only way I could see this turning into an error is if they expect, for example, iterators to be transferred to the other object in `std::vector`. Otherwise, it's either just a performance penalty (maybe) or a compile error if there's no copy constructor. – KABoissonneault Oct 03 '17 at 17:47
  • @KABoissonneault You have a point. However, when one cares to `move`, wouldn't he or she care about performance? I just think if they care, we should do too. – sandthorn Oct 03 '17 at 18:09
  • 1
    @sandthorn I am just not a fan of restricting your interface for needs your client _may_ or may not have. Sounds like a recipe for issues on github when you break your client's templates. If they care about performance, they will take the precautions they need – KABoissonneault Oct 03 '17 at 18:16
  • @KABoissonneault That's also good point. I guess I'm now convinced on _not_ `=delete`. Because I guess that const-ness should always be very obvious to performance savvy users after all. Thanks. – sandthorn Oct 03 '17 at 18:33
  • [stackoverflow.com/a/28595117/#28596435](https://stackoverflow.com/a/28595117/#28596435) : "ability for generic code to be resilient" so you really need that kind of fallback very bad. – sandthorn Oct 03 '17 at 19:03

1 Answers1

6
C::C(C const&&);

is what I call a const-qualified move constructor.

It informs the constructor that it (A) is coming from a discarded object, and (B) you are not allowed to mutate non-const components of the source object (as the object may actually be const, in which case mutating them is undefined behavior).

In the event that C contains mutable state, that state may be safely moved-from in some cases. In the event that it does not, it behaves much like a const&, unless the components of C have their own const&& move constructors.

In other circumstances, you may want to =delete it. I personally wouldn't.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Hadn't thought of the mutable members. That is a reasonable use case. – wally Oct 03 '17 at 17:09
  • @Yakk I think it should have a short nickname. Moreover, wouldn't 'const-qualified' suggest that the constructor might behave like const member function? I think it would be more confusing with that word. – sandthorn Oct 03 '17 at 17:58
  • 4
    @sandthorn No, short names are important when something is often talked about. The situations where this move constructor is worth bothering with are narrow and obscure. – Yakk - Adam Nevraumont Oct 03 '17 at 18:12
  • [stackoverflow.com/a/28595117/#28596435](https://stackoverflow.com/a/28595117/#28596435) : "ability for generic code to be resilient" : You don't really want to `=delete` it because you really want the copy fallback. – sandthorn Oct 03 '17 at 19:15