Title
Inconsistent defaulted move/copy members in pair and tuple
Status
resolved
Section
[pairs][tuple]
Submitter
INCITS

Created on 2010-08-25.00:00:00 last changed 170 months ago

Messages

Date: 2011-05-09.23:20:35

Proposed resolution:

See n3140.

Date: 2010-10-24.00:00:00

[ 2010-10-24 Daniel adds: ]

Accepting n3140 would solve this issue: The move/copy constructor will be defaulted, but the corresponding assignment operators need a non-default implementation because they are supposed to work for references as well.

Date: 2010-10-31.14:01:33

[ Resolution proposed by ballot comment: ]

Either remove "pair(const pair&) = default;" and "pair& operator=(pair&& p);" from pair's class definition in [pairs.pair] and from [pairs.pair] p.12-13, or give pair explicitly-defaulted copy/move constructors and copy/move assignment operators.
Change tuple to match.

Date: 2010-10-31.14:01:33

Addresses US-97

pair's class definition in N3092 [pairs.pair] contains "pair(const pair&) = default;" and "pair& operator=(pair&& p);". The latter is described by [pairs.pair] p.12-13.

"pair(const pair&) = default;" is a user-declared explicitly defaulted copy constructor. According to [class.copy]/10, this inhibits the implicitly-declared move constructor. pair should be move constructible. ([class.copy]/7 explains that "pair(pair<U, V>&& p)" will never be instantiated to move pair<T1, T2> to pair<T1, T2>.)
"pair& operator=(pair&& p);" is a user-provided move assignment operator (according to [dcl.fct.def.default]/4: "A special member function is user-provided if it is user-declared and not explicitly defaulted on its first declaration."). According to [class.copy]/20, this inhibits the implicitly-declared copy assignment operator. pair should be copy assignable, and was in C++98/03. (Again, [class.copy]/7 explains that "operator=(const pair<U, V>& p)" will never be instantiated to copy pair<T1, T2> to pair<T1, T2>.)
Additionally, "pair& operator=(pair&& p);" is unconditionally defined, whereas according to [class.copy]/25, defaulted copy/move assignment operators are defined as deleted in several situations, such as when non-static data members of reference type are present.

If "pair(const pair&) = default;" and "pair& operator=(pair&& p);" were removed from pair's class definition in [pairs.pair] and from [pairs.pair]/12-13, pair would receive implicitly-declared copy/move constructors and copy/move assignment operators, and [class.copy]/25 would apply. The implicitly-declared copy/move constructors would be trivial when T1 and T2 have trivial copy/move constructors, according to [class.copy]/13, and similarly for the assignment operators, according to[class.copy]/27. Notes could be added as a reminder that these functions would be implicitly-declared, but such notes would not be necessary (the Standard Library specification already assumes a high level of familiarity with the Core Language, and casual readers will simply assume that pair is copyable and movable).

Alternatively, pair could be given explicitly-defaulted copy/move constructors and copy/move assignment operators. This is a matter of style.

tuple is also affected. tuple's class definition in [tuple] contains:

tuple(const tuple&) = default;
tuple(tuple&&);
tuple& operator=(const tuple&);
tuple& operator=(tuple&&);

They should all be removed or all be explicitly-defaulted, to be consistent with pair. Additionally, [tuple.cnstr]/8-9 specifies the behavior of an explicitly defaulted function, which is currently inconsistent with pair.

History
Date User Action Args
2010-11-18 14:01:09adminsetstatus: nad editorial -> resolved
2010-11-11 03:10:11adminsetstatus: open -> nad editorial
2010-10-31 14:01:33adminsetmessages: + msg5210
2010-10-24 23:23:18adminsetmessages: + msg5089
2010-10-21 19:47:27adminsetmessages: + msg4794
2010-08-25 00:00:00admincreate