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.

### 823. `identity<void>` seems broken

Section: 22.2.4 [forward] Status: Resolved Submitter: Walter Brown Opened: 2008-04-09 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [forward].

View all issues with Resolved status.

Discussion:

N2588 seems to have added an `operator()` member function to the `identity<>` helper in 22.2.4 [forward]. I believe this change makes it no longer possible to instantiate `identity<void>`, as it would require forming a reference-to-`void` type as this `operator()`'s parameter type.

Suggested resolution: Specialize `identity<void>` so as not to require the member function's presence.

[ Sophia Antipolis: ]

> Jens: suggests to add a requires clause to avoid specializing on `void`.

> Alisdair: also consider cv-qualified `void`.

> Alberto provided proposed wording.

[ 2009-07-30 Daniel reopens: ]

> This issue became closed, because the `ReferentType` requirement fixed the problem - this is no longer the case. In retrospective it seems to be that the root of current issues around `std::identity` (823, 700, 939) is that it was standardized as something very different (an unconditional type mapper) than traditional usage indicated (a function object that should derive from `std::unary_function)`, as the SGI definition does. This issue could be solved, if `std::identity` is removed (one proposal of 939), but until this has been decided, this issue should remain open. An alternative for removing it, would be, to do the following:

> 1. Let `identity` stay as a real function object, which would now properly derive from `unary_function`:

>    >     template <class T> struct identity : unary_function<T, T> {
>    >       const T& operator()(const T&) const;
>    >     };

> 2. Invent (if needed) a generic type wrapper (corresponding to concept `IdentityOf`), e.g. `identity_of`, and move it's prototype description back to 22.2.4 [forward]:

>    >     template <class T> struct identity_of {
>    >       typedef T type;
>    >     };

>    and adapt the `std::forward` signature to use `identity_of` instead of `identity`.

[ 2009-10 Santa Cruz: ]

> Mark as NAD Editorial Resolved, fixed by 939.

Proposed resolution:

Change definition of `identity` in 22.2.4 [forward], paragraph 2, to:

>     template <class T>  struct identity {
>         typedef T type;

>         requires ReferentType<T>
>           const T& operator()(const T& x) const;
>       };

...

>       requires ReferentType<T>
>         const T& operator()(const T& x) const;

Rationale:

The point here is to able to write `T&` given `T` and `ReferentType` is precisely the concept that guarantees so, according to N2677 (Foundational concepts). Because of this, it seems preferable than an explicit check for `cv void` using `SameType/remove_cv` as it was suggested in Sophia. In particular, Daniel remarked that there may be types other than `cv void` which aren't referent types (`int[]`, perhaps?).