C++ Logo

std-discussion

Advanced search

Re: const-correctness - deleting const move constructor X(const X&&)

From: Daniel Krügler <daniel.kruegler_at_[hidden]>
Date: Sat, 17 Feb 2024 12:44:14 +0100
Am Fr., 16. Feb. 2024 um 22:22 Uhr schrieb Smith, Jim via
Std-Discussion <std-discussion_at_[hidden]>:
>
> Hi All,
>
> Deleting the const move constructor X(const&&) results in the default non-const move constructor also being deleted.

That is not quite right. The wording says that X(const X&&) is a move
constructor ([class.copy.ctor] p2). It also says in p8

"If the definition of a class X does not explicitly declare a move
constructor, a non-explicit one will be implicitly
declared as defaulted [...]"

So the constructor X(X&&) is not deleted in this case. It is just not
implicitly declared.

The difference between deleted and not declared is essential, since
when I have a deleted function, this is still considered during
overload resolution and would be a candidate. But once selected, the
program would be ill-formed. But if a constructor is not declared,
than overload resolution only attempts to find the best match of the
existing constructors. For example, given

struct X
{
  X();
  X(const X&&);
};

the line

 X x = X(); // OK

is well-formed, because the X(const X&&) constructor also accepts a
non-const rvalue of X.

> A const move constructor doesn't seem logical or maybe I'm missing something about the move feature in general.
>
> In the above is the not explicit deletion of the default non-const move constructor backed by the standard?

This is not what the standard says, see above. But what it says it
that once you have a user-declared move-constructor (or move
assignment operator), the implicitly declared *copy* constructor is
defined as deleted. Are you possibly mixing up the term move
constructor with copy constructor?

That leads to this variant of the example above, where the second line of

  X x1{};
  X x2 = x1; // Error

is ill-formed, because the implicitly deleted copy-constructor is a
better match here.

> I see in the standard under 'Copy/move constructors' 11.4.5.3 it says "X(const X&&) // OK, but possibly not sensible" so I'm concerned about it being used this way.
>

It valid, that you can have multiple move constructors defined in your
class. I hope I explained your original question above.

Thanks,

- Daniel

Received on 2024-02-17 11:44:26