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

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

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:(3.1) — If

`sizeof...(T)`

is zero, there shall be no member`type`

.(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) — 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`

.

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:(3.1) — If

`sizeof...(T)`

is zero, there shall be no member`type`

.(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) — 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>`

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

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

.~~[~~Let*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`

.`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: […]