The SGI STL provided an identity functor with
    an operator() that returned its argument, and this has been
    imitated in at least libstdc++.
template<class T>
class identity : public unary_function<T, T> {
  T& operator()(T& arg) const { return arg; }  // libstdc++ only?
  const T& operator()(const T& arg) const { return arg; }
};
    More recently, a need has arisen for an identity type transformation to
    select which of several function arguments should contribute to template
    argument deduction. (A no-longer-used definition
    of std::forward(), comparators in string_view,
    and in a suggestion for optional<> in c++std-lib-34391)
template<class T>
class identity {
  typedef T type;
};
    Some working drafts of C++11 defined an identity template
    that merged the two definitions (suggested by issue 700),
    but after issues 823
    and 939
    the whole class was removed.
The need for the identity type transformation and backward-compatibility with the SGI library are still around, so this paper proposes two (mutually exclusive) options for nearly achieving both.
decay or remove_referenceEvery potential use of identity<T>::type I'm familiar
    with could also be written as decay<T>::type or
    remove_reference<T>::type without significantly changing the
    meaning.  So why introduce an identity type transformation?
    Let's look at two uses, with identity replaced by
    remove_reference:
In c++std-lib-34400, Howard Hinnant suggested:
operator==(const optional<T>&, const typename remove_reference<T>::type&)
    in order to cause template argument deduction to proceed based on only
    the first argument to this operator==.  This prompted the
    reply, "Do we need remove_reference?  std::optional<U&> is
    not allowed." in c++std-lib-34402.  I expect that sort of question to come
    up often as we use this technique more without a dedicated
    identity transformation.  Experts will be able to figure out
    what's going on if they're paying attention, but users will assume that the
    transformation can actually change its argument.
In N3685, string_view, I suggest an implementation of comparison including:
template<typename charT, typename traits>
  bool operator==(basic_string_view<charT, traits> lhs,
                  typename __identity<basic_string_view<charT, traits>>::type rhs);
    My goal was the same here, to cause template argument deduction to
    proceed based on only one argument.  Replacing __identity with
    remove_reference would be confusing, since its argument is
    clearly not a reference.  Is basic_string_view an alias
    template which could result in a reference?  No, we're just using a
    term we don't mean because it's all the standard gives us.
The standard ought to give users the terminology they actually want.
Daniel Krugler suggested naming the type transformation
    "identity_of" to avoid conflicting with the SGI library and to
    match the IdentityOf concept in one of the C++11
    working drafts.  This is effectively the same definition as in the
    working paper in 2008 before issue 700 was applied, but it lives in
    <type_traits> instead of <utility>.
template <class T> struct identity_of;
template <class T>
  using identity_of_t = typename identity_of<T>::type;
      | Template | Condition | Comments | 
|---|---|---|
| template <class T> struct identity_of; | The member typedef type shall name T. | 
        
Arguably, identity_of_t<T> is not the teminology users
      actually want either.  For the uses I've seen, we actually want to exclude
      a function argument from template argument deduction.  So,
      omit_from_deduction<T> might be an even more useful alias
      template.
If we choose this option and someday decide to standardize the SGI
      identity function object type as well, we're likely to
      confuse users, who will wonder "What's the difference?  Which should I
      use?  Why do we not just have one of these?", as Howard Hinnant put it in
      an earlier draft of this paper.
Another option is to try to produce an identity template
    that makes everyone happy.  This implies that identity<T>::type ==
    T, an instance of identity<T> must be the identity
    function on values of type T, we have to fix issues 823
    and 939,
    and if we omit parts of the SGI definition, it must be possible to write a
    conforming extension that accepts the same programs as the SGI library.  I
    think this is nearly possible, although some code will be able to tell the
    difference.
If library vendors think this specification will be a problem, I would appreciate hearing your concerns.
We have some choices for how to specify operator() in a way
    that fixes issue 939:
const T& operator()(const T&) const;
template<class U> const U& operator()(const U&) const = delete;
        This is the solution 939 suggests. It definitely forbids
        implementations from accepting the same programs as the SGI definition
        would, since convertible-to-T arguments land on the explicitly-deleted
        function, but it fails to fix issue 823, meaning identity<const
        void> fails to instantiate.
const T& operator()(const T&) const;
T& operator()(T&) const;
template<class U> const U& operator()(const U&) const = delete;
        This matches the libstdc++ implementation more closely, but otherwise has the same problems as the previous option.
template<class U> U&& operator()(U&&) const;
        With "appropriate" "does not participate in overload resolution unless" wording. [member.functions] may allow an implementation to add another templated overload that captures convertible-to-T arguments, so that their users' calls can continue compiling. However, Daniel Krugler dislikes this interpretation, so it's probably a bad idea. Still, this gives us finer control over what arguments are accepted, so it may still be a good option. What should the enable_if condition be?
"decay<U>::type names the same type as (abbreviated
      "==" from here on) decay<T>::type": This allows
      identity<int[3]>{}(&an_int) to compile, which probably
      isn't ideal.
"decay<U>::type == T": This forbids
      identity<const int>{}(an_int).
"decay<U>::type ==
      remove_cv<T>::type": This forbids
      identity<int&>{}(3), which might be good, but which the
      SGI definition allows, but it also allows identity<volatile
      int>{}(an_int) and identity<int>{}(a_volatile_int),
      which we might or might not want.
// [function.objects.identity], identity:
template <class T=void> struct identity;
template <> struct identity<void>;
      template<class T = void> struct identity {
  template<class U> U&& operator()(U&&) const;
  typedef T argument_type;
  typedef T result_type;
  // [Note: The following typedef makes identity<T> a Transformation Trait ([meta.rqmts])
  // in addition to a function object type. -- end Note]
  typedef T type;
};
      template<class U> U&& operator()(U&& arg) const;
      Returns: std::forward<U>(arg).
Remarks: This function shall not participate in overload resolution unless <pick a choice of calls to accept>.
Notes: When arg is passed an lvalue, U
        will be an lvalue reference type, avoiding a copy or move.
template<> struct identity<void> {
  template<class U> U&& operator()(U&&) const;
  typedef unspecified is_transparent;
  typedef void type;
};
      template<class U> U&& operator()(U&& arg) const;
      Returns: std::forward<U>(arg).
Making identity::operator() a template solves issue
      823 by allowing the template to be instantiated without
      operator() being instantiable.
This proposal doesn't say that identity<T> derives from
      unary_function<T, T>.  I believe [derivation] says that an
      implementation can add such derivation as a conforming extension, and
      [diff.cpp03.utilities] explicitly calls out this removal as an
      incompatibility in other function objects, so it shouldn't be a problem
      for this object either.
It's not essential to provide the transparent version of
      identity<>, but it's consistent with the other function
      object types.  We might prefer to make identity a
      non-templated class that only provides this generic
      operator(), but that would both be incompatible with the SGI
      class and would require identity_of for the transformation
      trait.
Rvalue arguments produce xvalue results in this proposal, while they produce lvalue results in the SGI and libstdc++ implementations. Non-const lvalue arguments produce non-const lvalue results in this proposal and libstdc++, while the SGI documentation says they produce const lvalue results there.
For identity<T*>::operator(), 0 and
      nullptr cannot be arguments in this proposal, because they
      don't deduce to the right type.  The SGI interface would produce a safe
      result in that case.
I'd like to thank Daniel Krügler and Howard Hinnant for reviewing a draft of this paper and suggesting several improvements.