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

### 3141. `CopyConstructible` doesn't preserve source values

Section: 18.6 [concepts.object] Status: C++20 Submitter: Casey Carter Opened: 2018-07-07 Last modified: 2021-02-25

Priority: 2

View all issues with C++20 status.

Discussion:

The design intent of the `CopyConstructible` concept has always been that the source of the constructions it requires be left unmodified. Before P0541R1 reformulated the `Constructible` concept in terms of `is_constructible`, the wording which is now in 18.2 [concepts.equality]/5:

> This document uses a notational convention to specify which expressions declared in a requires-expression modify which inputs: except where otherwise specified, […] Operands that are constant lvalues or rvalues are required to not be modified.

indirectly enforced that requirement. Unfortunately, nothing in the current wording in 18.4.14 [concept.copyconstructible] enforces that requirement.

[2018-11 Reflector prioritization]

Set Priority to 2

Previous resolution: [SUPERSEDED]

> This wording is relative to N4762.

> Change 18.4.14 [concept.copyconstructible] as indicated:

> >     template<class T>
> >       concept CopyConstructible =
> >         MoveConstructible<T> &&
> >         Constructible<T, T&> && ConvertibleTo<T&, T> &&
> >         Constructible<T, const T&> && ConvertibleTo<const T&, T> &&
> >         Constructible<T, const T> && ConvertibleTo<const T, T>;

> > -1- If `T` is an object type, then let `v` be an lvalue of type (possibly `const`) `T` or an rvalue of type `const T`. `CopyConstructible<T>` is satisfied only if

> > (1.1) — After the definition `T u = v;`, `u` is equal to `v` and `v` is unmodified.

> > (1.2) — `T(v)` is equal to `v` and does not modify `v`.

[2020-02-13 Per LWG review, Casey provides updated P/R wording.]

[2020-02 Status to Immediate on Thursday night in Prague.]

Proposed resolution:

This wording is relative to N4849.

Change 18.4.14 [concept.copyconstructible] as indicated:

>     template<class T>
>       concept copy_constructible =
>         move_constructible<T> &&
>         constructible_from<T, T&> && convertible_to<T&, T> &&
>         constructible_from<T, const T&> && convertible_to<const T&, T> &&
>         constructible_from<T, const T> && convertible_to<const T, T>;

> -1- If `T` is an object type, then let `v` be an lvalue of type (possibly `const`) `T` or an rvalue of type `const T`. `T` models `copy_constructible` only if

> (1.1) — After the definition `T u = v;`, `u` is equal to `v` (18.2 [concepts.equality]) and `v` is not modified.

> (1.2) — `T(v)` is equal to `v` and does not modify `v`.