﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
    <meta charset="UTF-8"/>
    <title>The identity type transformation</title>
<style type="text/css">
body {color: #000000; background-color: #FFFFFF;}

del {text-decoration: line-through; color: #8B0040;}
ins {text-decoration: underline; color: #005100;}

pre code {display: inline-block; white-space: inherit}
code {white-space: nowrap}
code wbr {white-space: normal}
code .comment {white-space: pre-line; font-family: serif; font-style: italic}
code .comment code {font-style: normal}

/*
.wording { max-width: 90ex; }
.wording .sectnum { margin-right: 1em; }
.wording .sectname { display: block; float: right;  }

section.numbered { counter-reset: par-num; }
.wording p:before, .wording dt:before {
    content: counter(par-num) " "; counter-increment: par-num;
    font-size: 80%; position: absolute; left: 2em}
*/
.wording td { border-top: thin solid black; border-bottom: thin solid black; }

section.function { clear: both; }
.attributes, .attribute {margin-left: 2em}

.docinfo {float: right}
.docinfo p {margin: 0; text-align:right; font-style: italic}

section {padding-left: 16px}
section h2, section h3, section h4, section h5, section h6 {margin-left: -16px}

h2, h3, h4, h5, h6 { margin-bottom: .75em }
h5, h6 { font-size: 1em; }
.wording h4 { font-size: 1.17em }
p {margin-top: .5em; margin-bottom: .5em}
p:first-child, ul, ol {margin-top: 0}
.todo dt:not(:first-child) {margin-top: .5em}
p, li, dd, table {max-width: 80ex}

table { border: double; margin: 1em; border-collapse: collapse; }
td { text-align: left; }

.example {display: inline-block; clear: both; margin-left: 1ex;
          border: thin solid #0e0; background-color: #f8f8f8; padding: 1ex}

div.note > *:first-child::before {content: "Note: "; display: inline; font-weight: bold}
div.note {display: inline-block; margin-left: 1ex; border: thin solid #8f8;
          padding: 1ex; background-color: #efe}

:target {background-color: #fed}
</style>
</head>
<body>
  <header>
    <div class="docinfo">
      <p>ISO/IEC JTC1 SC22 WG21 N3766</p>
      <p>Date: <time pubdate="">2013-09-03</time></p>
      <address>
        <p>Jeffrey Yasskin &lt;<a href="mailto:jyasskin@google.com">jyasskin@google.com</a>&gt;</p>
      </address>
    </div>
    <h1>The identity type transformation</h1>
  </header>

  <p><small><a href="#maincontent">Skip table of contents</a></small></p>
  <nav id="toc"></nav>

  <a id="maincontent"></a>
  <section>
    <h2 id="overview">Overview</h2>
    <p>The SGI STL provided an <a
    href="http://www.sgi.com/tech/stl/identity.html">identity functor</a> with
    an <code>operator()</code> that returned its argument, and this has been
    imitated in at least <a
    href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/include/bits/stl_function.h?revision=195701&view=markup#l472">libstdc++</a>.</p>

    <pre><code>template&lt;class T>
class identity : public unary_function&lt;T, T> {
  T& operator()(T& arg) const { return arg; }  // libstdc++ only?
  const T& operator()(const T& arg) const { return arg; }
};</code></pre>

    <p>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 <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html">definition
    of std::forward()</a>, comparators in <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3685.html#h5o-8">string_view</a>,
    and in a suggestion for <code>optional&lt;></code> in c++std-lib-34391)</p>

    <pre><code>template&lt;class T>
class identity {
  typedef T type;
};</code></pre>

    <p>Some working drafts of C++11 defined an <code>identity</code> template
    that merged the two definitions (suggested by issue <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3688.html#700">700</a>),
    but after issues <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3688.html#823">823</a>
    and <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3688.html#939">939</a>
    the whole class was removed.</p>

    <p>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.</p>
  </section>

  <section>
    <h2 id="why">Just use <code>decay</code> or <code>remove_reference</code></h2>

    <p>Every potential use of <code>identity&lt;T>::type</code> I'm familiar
    with could also be written as <code>decay&lt;T>::type</code> or
    <code>remove_reference&lt;T>::type</code> without significantly changing the
    meaning.  So why introduce an <code>identity</code> type transformation?
    Let's look at two uses, with <code>identity</code> replaced by
    <code>remove_reference</code>:</p>

    <p>In c++std-lib-34400, Howard Hinnant suggested:</p>
    <pre class="example"><code>operator==(const optional&lt;T>&, const typename remove_reference&lt;T>::type&)</code></pre>
    <p>in order to cause template argument deduction to proceed based on only
    the first argument to this <code>operator==</code>.  This prompted the
    reply, "Do we need remove_reference?  <code>std::optional&lt;U&></code> 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
    <code>identity</code> 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.</p>

    <p>In <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3685.html#h5o-8">N3685,
    string_view</a>, I suggest an implementation of comparison including:</p>
    <pre class="example"><code>template&lt;typename charT, typename traits>
  bool operator==(basic_string_view&lt;charT, traits> lhs,
                  typename __identity&lt;basic_string_view&lt;charT, traits>>::type rhs);</code></pre>

    <p>My goal was the same here, to cause template argument deduction to
    proceed based on only one argument.  Replacing <code>__identity</code> with
    <code>remove_reference</code> would be confusing, since its argument is
    clearly not a reference.  Is <code>basic_string_view</code> an alias
    template which <em>could</em> result in a reference?  No, we're just using a
    term we don't mean because it's all the standard gives us.</p>

    <p>The standard ought to give users the terminology they actually want.</p>
  </section>

  <section>
    <h2 id="different-name">Use a different name</h2>

    <p>Daniel Krugler suggested naming the type transformation
    "<code>identity_of</code>" to avoid conflicting with the SGI library and to
    match the <code>IdentityOf</code> concept in one of the <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf">C++11
    working drafts</a>.  This is effectively the same definition as in <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf">the
    working paper in 2008</a> before issue 700 was applied, but it lives in
    &lt;type_traits> instead of &lt;utility>.</p>

    <section class="wording">
      <h3 id="different-name-wording">Wording</h3>

      <h4>In "Header &lt;type_traits> synopsis [meta.type.synop]", add to "other transformations":</h4>

      <pre><code>template &lt;class T> struct identity_of;
template &lt;class T>
  using identity_of_t = typename identity_of&lt;T>::type;</code></pre>

      <h4>Add to the table in "Other transformations [meta.trans.other]":</h4>

      <table>
        <tr><th>Template</th><th>Condition</th><th>Comments</th></tr>
        <tr>
          <td>template &lt;class T> struct identity_of;</td>
          <td></td>
          <td>The member typedef <code>type</code> shall name <code>T</code>.</td>
        </tr>
      </table>
    </section>

    <section>
      <h3 id="different-name-problems">Infelicities</h3>

      <p>Arguably, <code>identity_of_t&lt;T></code> 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,
      <code>omit_from_deduction&lt;T></code> might be an even more useful alias
      template.</p>

      <p>If we choose this option and someday decide to standardize the SGI
      <code>identity</code> 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.</p>
    </section>
  </section>

  <section>
    <h2 id="fixit">Fix the issues</h2>

    <p>Another option is to try to produce an <code>identity</code> template
    that makes everyone happy.  This implies that <code>identity&lt;T>::type ==
    T</code>, an instance of <code>identity&lt;T></code> must be the identity
    function on values of type <code>T</code>, we have to fix issues <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3688.html#823">823</a>
    and <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3688.html#939">939</a>,
    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.</p>

    <p>If library vendors think this specification will be a problem, I would
    appreciate hearing your concerns.</p>

    <p>We have some choices for how to specify <code>operator()</code> in a way
    that fixes issue 939:</p>
    <ul>
      <li>
        <pre><code>const T& operator()(const T&) const;
template&lt;class U> const U& operator()(const U&) const = delete;</code></pre>
        <p>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 <code>identity&lt;const
        void></code> fails to instantiate.</p>
      </li>
      <li>
        <pre><code>const T& operator()(const T&) const;
T& operator()(T&) const;
template&lt;class U> const U& operator()(const U&) const = delete;</code></pre>
        <p>This matches the libstdc++ implementation more closely, but otherwise
        has the same problems as the previous option.</p>
      </li>
      <li id="enable_if-choices">
        <pre><code>template&lt;class U> U&& operator()(U&&) const;</code></pre>
        <p>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?</p>
      </li>

      <li><p>"<code>decay&lt;U>::type</code> names the same type as (abbreviated
      "==" from here on) <code>decay&lt;T>::type</code>": This allows
      <code>identity&lt;int[3]>{}(&an_int)</code> to compile, which probably
      isn't ideal.</p></li>

      <li><p>"<code>decay&lt;U>::type</code> == <code>T</code>": This forbids
      <code>identity&lt;const int>{}(an_int)</code>.</p></li>

      <li><p>"<code>decay&lt;U>::type</code> ==
      <code>remove_cv&lt;T>::type</code>": This forbids
      <code>identity&lt;int&>{}(3)</code>, which might be good, but which the
      SGI definition allows, but it also allows <code>identity&lt;volatile
      int>{}(an_int)</code> and <code>identity&lt;int>{}(a_volatile_int)</code>,
      which we might or might not want.</p></li>

      <li>Others?</li>
    </ul>

    <section class="wording">
      <h3 id="fixit-wording">Wording</h3>

      <h4>To "Header &lt;functional> synopsis" in [function.objects], add:</h4>

      <pre><code>// [function.objects.identity], identity:
template &lt;class T=void> struct identity;
template &lt;> struct identity&lt;void>;</code></pre>

      <h4>Add a section [function.objects.identity] inside [function.objects]:</h4>

      <pre><code>template&lt;class T = void> struct identity {
  template&lt;class U> U&& operator()(U&&) const;
  typedef T argument_type;
  typedef T result_type;
  // [Note: The following typedef makes identity&lt;T> a Transformation Trait ([meta.rqmts])
  // in addition to a function object type. -- end Note]
  typedef T type;
};</code></pre>

      <pre><code>template&lt;class U> U&& operator()(U&& arg) const;</code></pre>
      <div class="attributes">
        <p><i>Returns</i>: <code>std::forward&lt;U>(arg)</code>.</p>
        <p><i>Remarks</i>: This function shall not participate in overload
        resolution unless <a href="#enable_if-choices"><i>&lt;pick a choice of calls to accept></i></a>.</p>
        <p><i>Notes</i>: When <code>arg</code> is passed an lvalue, <code>U</code>
        will be an lvalue reference type, avoiding a copy or move.</p>
      </div>

      <pre><code>template&lt;> struct identity&lt;void> {
  template&lt;class U> U&& operator()(U&&) const;
  typedef <i>unspecified</i> is_transparent;
  typedef void type;
};</code></pre>

      <pre><code>template&lt;class U> U&& operator()(U&& arg) const;</code></pre>
      <div class="attributes">
        <p><i>Returns</i>: <code>std::forward&lt;U>(arg)</code>.</p>
      </div>
    </section>

    <section>
      <h3 id="fixit-rationale">Rationale</h3>

      <p>Making <code>identity::operator()</code> a template solves <a
      href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3688.html#823">issue
      823</a> by allowing the template to be instantiated without
      <code>operator()</code> being instantiable.</p>

      <p>This proposal doesn't say that <code>identity&lt;T></code> derives from
      <code>unary_function&lt;T, T></code>.  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.</p>

      <p>It's not essential to provide the transparent version of
      <code>identity&lt;></code>, but it's consistent with the other function
      object types.  We might prefer to make <code>identity</code> a
      non-templated class that <em>only</em> provides this generic
      <code>operator()</code>, but that would both be incompatible with the SGI
      class and would require <code>identity_of</code> for the transformation
      trait.</p>
    </section>

    <section>
      <h3 id="fixit-infelicities">Infelicities</h3>

      <p>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.</p>

      <p>For <code>identity&lt;T*>::operator()</code>, <code>0</code> and
      <code>nullptr</code> 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.</p>
    </section>

  </section>

  <section>
    <h2 id="acknowledgements">Acknowledgements</h2>

    <p>I'd like to thank Daniel Krügler and Howard Hinnant for reviewing a draft
    of this paper and suggesting several improvements.</p>
  </section>

  <script type="text/javascript"><!--
/**
 * This code is compiled from h5o, with the patches in issues 18, 19, and 2
 * (https://code.google.com/p/h5o/issues/list).
 *
 * This code contains an implementation of HTML5 outlining algorithm, as described by WHATWG at [1]
 *
 * The copyright notice at [2] says:
 *              (c) Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA.
 *              You are granted a license to use, reproduce and create derivative works of this document.
 *
 * [1] http://www.whatwg.org/specs/web-apps/current-work/multipage/sections.html#outlines
 * [2] http://www.whatwg.org/specs/web-apps/current-work/multipage/index.html
 */
(function(){var j=function(b){this.sections=[];this.startingNode=b};j.prototype={heading:!1,append:function(b){b.container=this;this.sections.push(b)},asHTML:function(b){"object"!=typeof b&&(b={createLinks:b});var a;a=this.heading;g(a)?("HGROUP"==a.tagName.toUpperCase()&&(a=a.getElementsByTagName("h"+-k(a))[0]),a=a.textContent||a.innerText||"<i>No text content inside "+a.nodeName+"</i>"):a=""+a;if(b.createLinks){var e;a:{e=this.startingNode;for(var d,c=e;;){if(d=c.getAttribute("id")){e=d;break a}for(c=
c.firstChild;c&&3==c.nodeType&&!/\S/.test(c.data);)c=c.nextSibling;if(!g(c))break}do d="h5o-"+ ++q;while(r.getElementById(d));e.setAttribute("id",d);e=d}a='<a href="#'+e+'">'+a+"</a>"}return a+n(this.sections,b)}};var n=function(b,a){if(a.skipTopHeader)return a.skipTopHeader=!1,n(b[0].sections,a);for(var c="",d=0;d<b.length;d++){var f=b[d];a.skipUntitled&&"string"==typeof f.heading||(c+="<li>"+f.asHTML(a)+"</li>")}return""==c?c:"<ol>"+c+"</ol>"},s=function(b){b=b.heading;return g(b)?k(b):1},c,d,f,
q,r,t=function(b){if(!g(f[f.length-1]))if(l(b)||m(b))null!=c&&f.push(c),c=b,d=new j(b),c.outline={sections:[d],startingNode:b,asHTML:function(a){return n(this.sections,a)}};else if(null!=c&&g(b)){if(d.heading)if(k(b)>=s(c.outline.sections[c.outline.sections.length-1])){var a=new j(b);c.outline.sections.push(a);d=a;d.heading=b}else{var a=!1,e=d;do k(b)<s(e)&&(a=new j(b),e.append(a),d=a,d.heading=b,a=!0),e=e.container;while(!a)}else d.heading=b;f.push(b)}},p=function(b){return function(a){return a&&
a.tagName&&RegExp(b,"i").test(a.tagName.toUpperCase())}},m=p("^BLOCKQUOTE|BODY|DETAILS|FIELDSET|FIGURE|TD$"),l=p("^ARTICLE|ASIDE|NAV|SECTION$"),g=p("^H[1-6]|HGROUP$"),k=function(b){var a=b.tagName.toUpperCase();if("HGROUP"==a)for(a=1;6>=a;a++){if(0<b.getElementsByTagName("H"+a).length)return-a}else return-parseInt(a.substr(1))};HTML5Outline=function(b){q=0;r=b.ownerDocument||window.document;d=c=null;f=[];var a=b;a:for(;a;){t(a);if(a.firstChild){a=a.firstChild;continue a}for(;a;){var e=a,h=f[f.length-
1];if(g(h))h==e&&f.pop();else{if((l(e)||m(e))&&!d.heading)d.heading="<i>Untitled "+e.tagName.toUpperCase()+"</i>";if(l(e)&&0<f.length){c=f.pop();d=c.outline.sections[c.outline.sections.length-1];for(h=0;h<e.outline.sections.length;h++)d.append(e.outline.sections[h])}else if(m(e)&&0<f.length){c=f.pop();for(d=c.outline.sections[c.outline.sections.length-1];0<d.sections.length;)d=d.sections[d.sections.length-1]}else if(l(e)||m(e))d=c.outline.sections[0]}if(a.nextSibling){a=a.nextSibling;continue a}a=
a==b?null:a.parentNode}}return null!=c?c.outline:null}})();


    var outline = HTML5Outline(document.body);
    document.getElementById('toc').innerHTML =
        outline.asHTML({createLinks: true, skipTopHeader: true, skipUntitled: true});
  //--></script>
</body>
</html>
