### 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 10:48:01 UTC

**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`.