This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
[Moved to DR status at the April, 2013 meeting as paper N3667.]
Paragraphs 11 and 23 of 11.4.5.3 [class.copy.ctor] make adefaulted move constructor and assignment operator, respectively,deleted if there is a subobject with no corresponding movefunction and for which the copy operation is non-trivial. Thisseems excessive and unnecessary. For example:
template<typename T> struct wrap { wrap() = default; #ifdef USE_DEFAULTED_MOVE wrap(wrap&&) = default; #else wrap(wrap&& w) : t(static_cast<T&&>(w.t)) { } #endif wrap(const wrap&) = default; T t; }; struct S { S(){} S(const S&){} S(S&&){} }; typedef wrap<const S> W; W get() { return W(); } // Error, ifUSE_DEFAULTED_MOVE is defined, else OKIn this example the defaulted move constructor ofwrap is selected by overload resolution, but thismove-constructor is deleted, becauseS has notrivial copy-constructor.
I think that we overshoot here with the delete rules: I see noproblem for the defaulted move-constructor in this example. Ourtriviality-deduction rules already cover this case (11.4.5.3 [class.copy.ctor] paragraph 12:W::W(W&&) is nottrivial) and our exception-specification rules (14.5 [except.spec] paragraph 14) already correctly deduce anoexcept(false) specification forW::W(W&&).
It would still be OK to prevent that a move-constructorwould be generated for the following example where nouser-declared defaulted copy/move members are present:
template<typename T> struct wrap_2 { wrap_2() = default; T t; }; typedef wrap_2<const S> W2; W2 get() { return W2(); } // OK, selects copy constructorif we want. This would mean that we add a new bulletto 11.4.5.3 [class.copy.ctor] paragraph 9 and paragraph 20.
Proposed resolution (February, 2012):
Change 11.4.5.3 [class.copy.ctor] paragraph 9 as follows:
If the definition of a classX does not explicitly declarea move constructor, one will be implicitly declared as defaulted ifand only if
...
X does not have a user-declared destructor,
andthe move constructor would not be implicitly defined asdeleted
., andeach ofX's non-static data members and direct orvirtual base classes has a type that either has a move constructor oris trivially copyable.
[Note:...
Change 11.4.5.3 [class.copy.ctor] paragraph 11 as follows:
An implicitly-declared copy/move constructor is aninlinepublic member of its class. A defaulted copy/move constructor fora classX is defined as deleted (9.6.3 [dcl.fct.def.delete])ifX has:
...
any direct or virtual base class or non-static data member of atype with a destructor that is deleted or inaccessible from thedefaulted constructor,or
for the copy constructor, a non-static data member of rvaluereference type.
, or
for the move constructor, a non-static data member ordirect or virtual base class with a type that does not have a moveconstructor and is not trivially copyable.
Change 11.4.5.3 [class.copy.ctor] paragraph 20 as follows:
If the definition of a classX does not explicitly declarea move assignment operator, one will be implicitly declared asdefaulted if and only if
...
X does not have a user-declared destructor,
andthe move assignment operator would not be implicitly defined asdeleted
.,X has no direct or indirect virtual base classwith a non-trivial move assignment operator, and
each ofX's non-static data members and direct orvirtual base classes has a type that either has a move assignmentoperator or is trivially copyable.
Example:...
Change 11.4.5.3 [class.copy.ctor] paragraph 23 as follows:
A defaulted copy/move assignment operator for classX isdefined as deleted ifX has:
...
a direct or virtual base classB that cannot becopied/moved because overload resolution (12.2 [over.match]),as applied toB's corresponding assignment operator, resultsin an ambiguity or a function that is deleted or inaccessible from thedefaulted assignment operator.
, or
for the move assignment operator, a non-static data member ordirect base class with a type that does not have a move assignmentoperator and is not trivially copyable, or any direct or indirectvirtual base class.
Additional notes (August, 2012):
The proposed resolution was extensively discussed and additional alternatives weresuggested. A paper is being produced for the October, 2012 meeting describingthe various options, so the issue has been returned to "review" statusto wait for the outcome of that deliberation.
See also the discussion ofissue 1491 foradditional considerations.
Proposed resolution (December, 2012):
Change 11.4.5.3 [class.copy.ctor] paragraph 9 asfollows:
If the definition of a classX does not explicitly declarea move constructor, one will be implicitly declared as defaulted ifand only if
X does not have a user-declared copy constructor,
X does not have a user-declared copy assignmentoperator,
X does not have a user-declared move assignmentoperator,and
X does not have a user-declareddestructor.
, and
the move constructor would not be implicitly defined asdeleted.[Note:...
Change 11.4.5.3 [class.copy.ctor] paragraph 11 as follows:
...A defaulted copy/move constructor for a classX isdefined as deleted (9.6.3 [dcl.fct.def.delete]) ifX has:
a variant member with a non-trivial correspondingconstructor andX is a union-like class,
a non-static data member of class typeM (or arraythereof) that cannot be copied/moved because overload resolution(12.2 [over.match]), as applied toM's correspondingconstructor, results in an ambiguity or a function that is deleted orinaccessible from the defaulted constructor,
a direct or virtual base classB that cannot becopied/moved because overload resolution (12.2 [over.match]),as applied toB's corresponding constructor, results in anambiguity or a function that is deleted or inaccessible from thedefaulted constructor,
any direct or virtual base class or non-static data member of atype with a destructor that is deleted or inaccessible from thedefaulted constructor,or
for the copy constructor, a non-static data member of rvaluereference type.
, or
for the move constructor, a non-static data member ordirect or virtual base class with a type that does not have a moveconstructor and is not trivially copyable.A defaulted move constructor that is defined as deleted isignored by overload resolution (12.2 [over.match]).[Note: A deleted move constructor would otherwise interferewith initialization from an rvalue which can use the copy constructorinstead. —end note]
Change 11.4.5.3 [class.copy.ctor] paragraph 20 as follows:
If the definition of a classX does not explicitly declarea move assignment operator, one will be implicitly declared asdefaulted if and only if
X does not have a user-declared copyconstructor,
X does not have a user-declared moveconstructor,
X does not have a user-declared copy assignmentoperator,and
X does not have a user-declareddestructor.
, and
the move assignment operator would not be implicitlydefined as deleted.[Example:...
Change 11.4.5.3 [class.copy.ctor] paragraph 23 as follows:
A defaulted copy/move assignment operator for classX isdefined as deleted ifX has:
a variant member with a non-trivial corresponding assignmentoperator andX is a union-like class, or
a non-static data member of const non-class type (or arraythereof), or
a non-static data member of reference type, or
a non-static data member of class typeM (or arraythereof) that cannot be copied/moved because overload resolution(12.2 [over.match]), as applied toM's correspondingassignment operator, results in an ambiguity or a function that isdeleted or inaccessible from the defaulted assignment operator,or
a direct or virtual base classB that cannot becopied/moved because overload resolution (12.2 [over.match]),as applied toB's corresponding assignment operator, resultsin an ambiguity or a function that is deleted or inaccessible from thedefaulted assignment operator.
, or
for the move assignment operator, a non-static data memberor direct base class with a type that does not have a move assignmentoperator and is not trivially copyable, or any direct or indirectvirtual base class.A defaulted move assignment operator that is defined as deleted isignored by overload resolution (12.2 [over.match],12.3 [over.over]).
This resolution also resolvesissue 1491.