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

### 2460. LWG issue 2408 and value categories

Section: 20.15.8.7 [meta.trans.other], 23.3.2.3 [iterator.traits] Status: C++17 Submitter: Richard Smith Opened: 2014-11-19 Last modified: 2017-07-30

Priority: 2

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

View all issues with C++17 status.

Discussion:

LWG issue 2408 changes the meat of the specification of `common_type` to compute:

> […] the type, if any, of an unevaluated conditional expression (5.16) 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`.

This has an effect on the specification that I think was unintended. It used to be the case that `common_type<T&, U&&>` would consider the type of a conditional between an lvalue of type `T` and an xvalue of type `U`. It's now either invalid (because there is no such thing as an xvalue of reference type) or considers the type of a conditional between an xvalue of type `T` and an xvalue of type `U`, depending on how you choose to read it.

Put another way, this has the effect of changing the usual definition from:

>     typedef decay_t<decltype(true ? declval<T>() : declval<U>())> type;

to:

>     typedef decay_t<decltype(true ? declval<remove_reference_t<T>>() : declval<remove_reference_t<U>>())> type;

It also makes `common_type` underspecified in the case where one of the operands is of type `void`; in that case, the resulting type depends on whether the expression is a throw-expression, which is not specified (but used to be).

Also on the subject of this wording: the changes to 23.3.2.3 [iterator.traits] say that `iterator_traits<T>` "shall have no members" in some cases. That's wrong. It's a class type; it always has at least a copy constructor, a copy assignment operator, and a destructor. Plus this removes the usual library liberty to add additional members with names that don't collide with normal usage (for instance, if a later version of the standard adds members, they can't be present here as a conforming extension). Perhaps this should instead require that the class doesn't have members with any of those five names? That's what 2408 does for `common_type`'s type member.

[2016-08 Chicago]

This issue has two parts, one dealing with `common_type`, the other with `iterator_traits`. The first of these is resolved by 2465. See below for the proposed resolution for the other one.

Wed PM: Move to Tentatively Ready

Proposed resolution:

Change 23.3.2.3 [iterator.traits] p.2:

[…] as publicly accessible members and no other members:

[…]

Otherwise, `iterator_traits<Iterator>` shall have no members by any of the above names.