<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
  
  <style type="text/css">
.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt
{
    font-weight: bold;
}
    
.ins {
    background-color:#A0FFA0;
}

.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
  </style>
  <title>Wording for Addressing Tuples by Type</title>

  
</head><body>
<p>N3584<br/>

2013-03-14<br/>

Mike Spertus, Symantec<br/>

<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a><br/>

<br/></p>

<h1>Wording for Addressing Tuples by Type</h1>

<p>In Portland, LWG accepted the "Addressing <span style="font-family: monospace;">tuple</span>s by type" portion of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3404.html">n3404</a>,
pending wording, which is provided below.
Note that the "Functoriality" proposal in that paper was not accepted.</p>

<h2>Overview<br/>
</h2>

N3404 proposed allowing <span style="font-family: monospace;">tuple</span>s
to be addressed by type as well as by numerical index.<br/>

<code>tuple&lt;string, string, int&gt; t("foo", "bar", 7);
int i = get&lt;int&gt;(t);<span class="comment"> // i == 7</span>
int j = get&lt;2&gt;(t); <span class="comment"> // Equivalent to the above: j == 7</span>
string s = get&lt;string&gt;(t);<span class="comment"> // Compile-time error. Ambiguous</span></code>
<h2>Wording</h2>
    <p>Add the following after &sect;20.4.2.6p7 [tuple.elem]:</p>
<blockquote><pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class... Types&gt;</span>
<span class="ins">  T&amp; get(tuple&lt;Types...&gt;&amp; t) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> The type <tt>T</tt> occurs 
        exactly once in <tt>Types...</tt>. Otherwise, the program is ill-formed.</span><br />
        <span class="ins"><em>Returns:</em> A reference to the element of <tt>t</tt> corresponding to the type <tt>T</tt> in <tt>Types...</tt></span></blockquote>
    <pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class... Types&gt;</span>
  <span class="ins">T&amp;&amp; get(tuple&lt;Types...&gt;&amp;&amp; t) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Effects:</em> Equivalent to return <tt>std::forward&lt;T&amp;&amp;&gt;(get&lt;i&gt;(t));</tt></span><br />
        <span class="ins"><em>Note:</em> if a <tt>T</tt> in Types is some reference type <tt>X&amp;</tt>, the 
    return type is <tt>X&amp;</tt>, not <tt>X&amp;&amp;</tt>. However, if the element type is a non-reference type 
    <tt>T</tt>, the return type is <tt>T&amp;&amp;</tt>.</span></blockquote>
    <pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class... Types&gt;</span>
  <span class="ins">T&amp; get(const tuple&lt;Types...&gt;&amp; t) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> The type <tt>T</tt> occurs 
        exactly once in <tt>Types...</tt>. Otherwise, the program is ill-formed.</span><br />
        <span class="ins"><em>Returns:</em> A const reference to the element of <tt>t</tt> corresponding to the type <tt>T</tt> in <tt>Types...</tt></span><br />
        <br />
        <span class="ins">[ <em>Note:</em> Constness is shallow. If a <tt>T</tt> in Types is some 
    reference type <tt>X&amp;</tt>, the return type is <tt>X&amp;</tt>, not <tt>const X&amp;</tt>. However, if the element 
    type is non-reference type <tt>T</tt>, the return type is <tt>const T&amp;</tt>. This is consistent 
    with how constness is defined to work for member variables of reference type.<em> <br/>
     end note</em> ]</span><br/>
		<br/>
		<span class="ins">[ <em>Example:</em><tt style="padding:0;margin:0"><br/><br/>
<span class="ins">const tuple&lt;int, const int, double, double&gt; t(1, 2, 3.4, 5.6);<br/>
const int &amp;i1(get&lt;int&gt;(t) <span class="comment"> // OK. Not ambiguous. i1 == 1</span><br/>
const int &amp;i2(get&lt;const int&amp;gt;(t) <span class="comment"> // OK. Not ambiguous. i2 == 2</span><br/> 
const double &amp;d(get&lt;double&gt;(t) <span class="comment"> // ERROR. ill-formed</span><br/>
<br/>
</span></tt><em> end example</em> ]</span></blockquote></blockquote>
		
		<p>Add the following to the end of &sect;20.3.4 [pair.astuple]:</p>
<blockquote>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  T&amp; get(pair&lt;T, U&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  const T&amp; get(const pair&lt;T, U&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  T&amp;&amp; get(pair&lt;T, U&gt;&amp;&amp; p) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> <tt>T</tt> and 
        <tt>U</tt> are distinct types. Otherwise, the program is ill-formed.</span><br />
        <span class="ins"><em>Returns:</em> <tt>get&lt;0&gt;(p);</tt></span></blockquote>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  T&amp; get(pair&lt;U, T&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  const T&amp; get(const pair&lt;U, T&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  T&amp;&amp; get(pair&lt;U, T&gt;&amp;&amp; p) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> <tt>T</tt> and 
        <tt>U</tt> are distinct types. Otherwise, the program is ill-formed.</span><br />
        <span class="ins"><em>Returns:</em> <tt>get&lt;1&gt;(p);</tt></span></blockquote></blockquote>
</body></html>