This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 1383. Inconsistent defaulted move/copy members in `pair` and `tuple`

Section: 20.4 [pairs], 20.5 [tuple] Status: Resolved Submitter: INCITS Opened: 2010-08-25 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [pairs].

View all issues with Resolved status.

Discussion:

Addresses US-97

`pair`'s class definition in N3092 20.4.2 [pairs.pair] contains "`pair(const pair&) = default;`" and "`pair& operator=(pair&& p);`". The latter is described by 20.4.2 [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 9.5.2 [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 20.4.2 [pairs.pair] and from 20.4.2 [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 20.5 [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, 20.5.3.1 [tuple.cnstr]/8-9 specifies the behavior of an explicitly defaulted function, which is currently inconsistent with `pair`.

[ Resolution proposed by ballot comment: ]

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

[ 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.

Proposed resolution:

See n3140.