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

### 2763. `common_type_t<void, void>` is undefined

Section: 21.3.8.7 [meta.trans.other] Status: Resolved Submitter: Tim Song Opened: 2016-08-10 Last modified: 2016-11-21

Priority: 2

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

View all issues with Resolved status.

Discussion:

There are no xvalues of type cv `void` (see [basic.lval]/6), so the current wording appears to mean that there is no `common_type_t<void, void>`. Is that intended?

[2016-08-11, Daniel comments]

This is strongly related to LWG 2465. It should be considered to resolve 2465 by this revised wording.

[2016-11-12, Issaquah]

Resolved by P0435R1

Proposed resolution:

This wording is relative to N4606.

1. Edit 21.3.8.7 [meta.trans.other]/3 as indicated:

   > [Drafting note: The proposed wording below simply goes back to using `declval`, which already does the right thing. To describe this in words would be something like "if `D1` is `void`, a prvalue of type `void` that is not a (possibly parenthesized) throw-expression, otherwise an xvalue of type `D1`", which seems unnecessarily convoluted at best. — end drafting note]

   > For the `common_type` trait applied to a parameter pack `T` of types, the member `type` shall be either defined or not present as follows:

   > 1. (3.1) — If `sizeof...(T)` is zero, there shall be no member `type`.

   > 2. (3.2) — If `sizeof...(T)` is one, let `T0` denote the sole type in the pack `T`. The member typedef `type` shall denote the same type as `decay_t<T0>`.

   > 3. (3.3) — If `sizeof...(T)` is greater than two, let `T1`, `T2`, and `R`, respectively, denote the first, second, and (pack of) remaining types comprising `T`. [Note: `sizeof...(R)` may be zero. — end note] Let `C` denote the type, if any, of an unevaluated conditional expression (7.6.16 [expr.cond]) whose first operand is an arbitrary value of type `bool`, whose second operand is an xvalue of type `T1` `declval<T1>()`, and whose third operand is an xvalue of type `T2` `declval<T2>()`. If there is such a type `C`, the member typedef `type` shall denote the same type, if any, as `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.

2. The following wording is a merge of the above with the current proposed resolution of 2465, to provide editorial guidance if both proposed resolutions are accepted:

   > -3- Note A: For the `common_type` trait applied to a parameter pack `T` of types, the member `type` shall be either defined or not present as follows:

   > 1. (3.1) — If `sizeof...(T)` is zero, there shall be no member `type`.

   > 2. (3.2) — If `sizeof...(T)` is one, let `T0` denote the sole type in the pack `T`. The member typedef `type` shall denote the same type as `decay_t<T0>`.

   > 3. (3.3) — If `sizeof...(T)` is two, let `T1` and `T2`, respectively, denote the first and second types comprising `T`, and let `D1` and `D2`, respectively, denote `decay_t<T1>` and `decay_t<T2>`.

   >    1. (3.3.1) — If `is_same_v<T1, D1>` and `is_same_v<T2, D2>`, let `C` denote the type of an unevaluated conditional expression (7.6.16 [expr.cond]) whose first operand is an arbitrary value of type `bool`, whose second operand is `declval<D1>()`, and whose third operand is `declval<D2>()`. [Note: This will not apply if there is a specialization `common_type<D1, D2>`. — end note]

   >    2. (3.3.2) — Otherwise, let `C` denote the type `common_type_t<D1, D2>`.

   >    In either case, if there is such a type `C`, the member typedef `type` shall denote `C`. Otherwise, there shall be no member `type`.

   > 4. (3.4) — If `sizeof...(T)` is greater than one two, let `T1`, `T2`, and `R`, respectively, denote the first, second, and (pack of) remaining types comprising `T`. [Note: `sizeof...(R)` may be zero. — end note] Let `C` denote the type, if any, of an unevaluated conditional expression (7.6.16 [expr.cond]) whose first operand is an arbitrary value of type `bool`, whose second operand is an xvalue of type `T1`, and whose third operand is an xvalue of type `T2`. Let `C` denote `common_type_t<T1, T2>`. If there is such a type `C`, the member typedef `type` shall denote the same type, if any, as `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.

   > -?- Note B: A program may specialize the `common_type` trait for two cv-unqualified non-reference types if at least one of them is a user-defined type. [Note: Such specializations are needed when only explicit conversions are desired among the template arguments. — end note] Such a specialization need not have a member named `type`, but if it does, that member shall be a typedef-name for a cv-unqualified non-reference type that need not otherwise meet the specification set forth in Note A, above.

   > -4- [Example: Given these definitions: […]