**Section:** 21.3.8.7 [meta.trans.other] **Status:** C++20
**Submitter:** Casey Carter **Opened:** 2020-01-23 **Last modified:** 2021-02-25 10:48:01 UTC

**Priority: **0

**View all other** issues in [meta.trans.other].

**View all issues with** C++20 status.

**Discussion:**

There are two paragraphs in the the definition of `common_type`:

Otherwise, if both

`D1`and`D2`denote comparison category types (17.11.2.1 [cmp.categories.pre]), let`C`denote the common comparison type (11.10.3 [class.spaceship]) of`D1`and`D2`.Otherwise, if

`decay_t<decltype(false ? declval<D1>() : declval<D2>())>`denotes a valid type, let`C`denote that type.

P1614R2 added the first bullet so that
`common_type_t<strong_equality, T>` would be the same type as
`common_comparison_category_t<strong_equality, T>`; other cases are correctly handled
by the second (pre-existing) bullet. After application of P1959R0
in Belfast, `std::strong_equality` is no more. We can now strike the first bullet without
changing the behavior of `common_type`.

*[2020-02-08 Status set to Tentatively Ready after seven positive votes on the reflector.]*

**Proposed resolution:**

This wording is relative to N4849.

Modify 21.3.8.7 [meta.trans.other] as indicated:

-3- Note A: For the

`common_type`trait applied to a template parameter pack`T`of types, the member`type`shall be either defined or not present as follows:(3.1) — […]

[…]

(3.3) — If

`sizeof...(T)`is two, let the first and second types constituting`T`be denoted by`T1`and`T2`, respectively, and let`D1`and`D2`denote the same types as`decay_t<T1>`and`decay_t<T2>`, respectively.(3.3.1) — If

`is_same_v<T1, D1>`is`false`or`is_same_v<T2, D2>`is`false`, let`C`denote the same type, if any, as`common_type_t<D1, D2>`.(3.3.2) — [

*Note:*None of the following will apply if there is a specialization`common_type<D1, D2>`. —*end note*]~~(3.3.3) — Otherwise, if both~~`D1`and`D2`denote comparison category types (17.11.2.1 [cmp.categories.pre]), let`C`denote the common comparison type (11.10.3 [class.spaceship]) of`D1`and`D2`.(3.3.4) — Otherwise, if

decay_t<decltype(false ? declval<D1>() : declval<D2>())>

denotes a valid type, let

`C`denote that type.(3.3.5) — […]

[…]