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.

### 3154. `Common` and `CommonReference` have a common defect

Section: 18.4.6 [concept.common] Status: C++20 Submitter: Casey Carter Opened: 2018-08-10 Last modified: 2021-02-25

Priority: 0

View all other issues in [concept.common].

View all issues with C++20 status.

Discussion:

The semantic requirements of both `Common` (18.4.6 [concept.common]):

> -2- Let `C` be `common_type_t<T, U>`. Let `t` be a function whose return type is `T`, and let `u` be a function whose return type is `U`. `Common<T, U>` is satisfied only if:

> (2.1) — `C(t())` equals `C(t())` if and only if `t()` is an equality-preserving expression (18.2 [concepts.equality]).

> (2.2) — `C(u())` equals `C(u())` if and only if `u()` is an equality-preserving expression (18.2 [concepts.equality]).

and similarly `CommonReference` ( [concept.commonreference]):

> -2- Let `C` be `common_reference_t<T, U>`. Let `t` be a function whose return type is `T`, and let `u` be a function whose return type is `U`. `CommonReference<T, U>` is satisfied only if:

> (2.1) — `C(t())` equals `C(t())` if and only if `t()` is an equality-preserving expression (18.2 [concepts.equality]).

> (2.2) — `C(u())` equals `C(u())` if and only if `u()` is an equality-preserving expression.

don't properly reflect the intended design that conversions to the common type / common reference type are identity-preserving: in other words, that converting two values to the common type produces equal results if and only if the values were initially equal. The phrasing "`C(E)` equals `C(E)` if and only if `E` is an equality-preserving expression" is also clearly defective regardless of the intended design: the assertion "`E` is not equality-preserving" does not imply that every evaluation of `E` produces different results.

[2018-08 Batavia Monday issue prioritization]

Priority set to 0, status to 'Tentatively Ready'

[2018-11, Adopted in San Diego]

Proposed resolution:

This wording is relative to N4762.

1. Modify 18.4.5 [concept.commonref] p2 as follows:

   > -2- Let `C` be `common_reference_t<T, U>`. Let `t` be a function whose return type is `t1` and `t2` be equality-preserving expressions (18.2 [concepts.equality]) such that `decltype((t1))` and `decltype((t2))` are each `T`, and let `u` be a function whose return type is `u1` and `u2` be equality-preserving expressions such that `decltype((u1))` and `decltype((u2))` are each `U`. `T` and `U` model `CommonReference<T, U>` is satisfied only if:

   > (2.1) — `C(t1())` equals `C(t2())` if and only if `t1()` equals `t2`, and is an equality-preserving expression (18.2 [concepts.equality]).

   > (2.2) — `C(u1())` equals `C(u2())` if and only if `u1()` equals `u2` is an equality-preserving expression.

2. Modify 18.4.6 [concept.common] p2 similarly:

   > -2- Let `C` be `common_type_t<T, U>`. Let `t` be a function whose return type is `t1` and `t2` be equality-preserving expressions (18.2 [concepts.equality]) such that `decltype((t1))` and `decltype((t2))` are each `T`, and let `u` be a function whose return type is `u1` and `u2` be equality-preserving expressions such that `decltype((u1))` and `decltype((u2))` are each `U`. `T` and `U` model `Common<T, U>` is satisfied only if:

   > (2.1) — `C(t1())` equals `C(t2())` if and only if `t1()` equals `t2`, and is an equality-preserving expression (18.2 [concepts.equality]).

   > (2.2) — `C(u1())` equals `C(u2())` if and only if `u1()` equals `u2` is an equality-preserving expression (18.2 [concepts.equality]).