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

.