6
votes

When defining a class, is the following valid?

T(const T&&) = default;

I was reading about move constructors here and it explains how the default may still be implicitly declared:

A class can have multiple move constructors, e.g. both T::T(const T&&) and T::T(T&&). If some user-defined move constructors are present, the user may still force the generation of the implicitly declared move constructor with the keyword default.

At the bottom of the page it mentions defect report CWG 2171:

CWG 2171 C++14
X(const X&&) = default was non-trivial, made trivial.

Maybe the wiki entry just has a mistake and CWG 2171 is only referring to a copy constructor, not a move constructor?

1
Why wouldn't it be valid? - Lightness Races in Orbit
Valid, but rather useless, I would say - how would you move from it? - SergeyA
@LightnessRacesinOrbit I couldn't find a compiler that will compile it. - wally
@SergeyA I agree that it is rather useless. A user defined one might still have a purpose. But as to the validity; are you able to compile a class that has X(const X&&) = default? - wally
Anyway, now fixed. The P/R of that issue is a bit misleading since it appeared to touch copy/move equally, but as pointed out below [dcl.fct.def.default]/1.2 prevents anything but X&& from being non-user-provided. - T.C.

1 Answers

3
votes

From the n4296 draft:

8.4.2.1 Explicitly-defaulted functions:

A function that is explicitly defaulted shall

(1.1) — be a special member function,

(1.2) — have the same declared function type (except for possibly differing ref-qualifiers and except that in the case of a copy constructor or copy assignment operator, the parameter type may be “reference to non-const T”, where T is the name of the member function’s class) as if it had been implicitly declared, and

(1.3) — not have default arguments.

12.8.10 Copying and moving class objects:

The implicitly-declared move constructor for class X will have the form X::X(X&&)


As a consequence the line:

T(const T&&) = default;

is not valid because the implicitly-declared move constructor has the form of:

T(T&&)