common_type_t<void, void>
is undefinedSection: 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 "ifD1
isvoid
, a prvalue of typevoid
that is not a (possibly parenthesized) throw-expression, otherwise an xvalue of typeD1
", which seems unnecessarily convoluted at best. — end drafting note]
For the
common_type
trait applied to a parameter packT
of types, the membertype
shall be either defined or not present as follows:
(3.1) — If
sizeof...(T)
is zero, there shall be no membertype
.(3.2) — If
sizeof...(T)
is one, letT0
denote the sole type in the packT
. The member typedeftype
shall denote the same type asdecay_t<T0>
.(3.3) — If
sizeof...(T)
is greater than two, letT1
,T2
, andR
, respectively, denote the first, second, and (pack of) remaining types comprisingT
. [Note:sizeof...(R)
may be zero. — end note] LetC
denote the type, if any, of an unevaluated conditional expression (7.6.16 [expr.cond]) whose first operand is an arbitrary value of typebool
, whose second operand isan xvalue of typeT1
declval<T1>()
, and whose third operand isan xvalue of typeT2
declval<T2>()
. If there is such a typeC
, the member typedeftype
shall denote the same type, if any, ascommon_type_t<C, R...>
. Otherwise, there shall be no membertype
.
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 packT
of types, the membertype
shall be either defined or not present as follows:
(3.1) — If
sizeof...(T)
is zero, there shall be no membertype
.(3.2) — If
sizeof...(T)
is one, letT0
denote the sole type in the packT
. The member typedeftype
shall denote the same type asdecay_t<T0>
.(3.3) — If
sizeof...(T)
is two, letT1
andT2
, respectively, denote the first and second types comprisingT
, and letD1
andD2
, respectively, denotedecay_t<T1>
anddecay_t<T2>
.
(3.3.1) — If
is_same_v<T1, D1>
andis_same_v<T2, D2>
, letC
denote the type of an unevaluated conditional expression (7.6.16 [expr.cond]) whose first operand is an arbitrary value of typebool
, whose second operand isdeclval<D1>()
, and whose third operand isdeclval<D2>()
. [Note: This will not apply if there is a specializationcommon_type<D1, D2>
. — end note](3.3.2) — Otherwise, let
C
denote the typecommon_type_t<D1, D2>
.In either case, if there is such a type
C
, the member typedeftype
shall denoteC
. Otherwise, there shall be no membertype
.(3.4) — If
sizeof...(T)
is greater thanonetwo, letT1
,T2
, andR
, respectively, denote the first, second, and (pack of) remaining types comprisingT
.[Note:Letsizeof...(R)
may be zero. — end note] LetC
denote the type, if any, of an unevaluated conditional expression (7.6.16 [expr.cond]) whose first operand is an arbitrary value of typebool
, whose second operand is an xvalue of typeT1
, and whose third operand is an xvalue of typeT2
.C
denotecommon_type_t<T1, T2>
. If there is such a typeC
, the member typedeftype
shall denote the same type, if any, ascommon_type_t<C, R...>
. Otherwise, there shall be no membertype
.-?- Note B: A program may specialize the
-4- [Example: Given these definitions: […]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 namedtype
, 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.