<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1118: tuple query APIs do not support cv-qualification</title>
<meta property="og:title" content="Issue 1118: tuple query APIs do not support cv-qualification">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1118.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++11">C++11</a> status.</em></p>
<h3 id="1118"><a href="lwg-defects.html#1118">1118</a>. <code>tuple</code> query APIs do not support cv-qualification</h3>
<p><b>Section:</b> 22.4.7 <a href="https://wg21.link/tuple.helper">[tuple.helper]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2009-05-23 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#tuple.helper">issues</a> in [tuple.helper].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The APIs <code>tuple_size</code> and <code>tuple_element</code> do not support
cv-qualified <code>tuple</code>s, <code>pair</code>s or <code>array</code>s.
</p>
<p>
The most generic solution would be to supply partial specializations once
for each cv-type in the <code>tuple</code> header.  However, requiring this header for
cv-qualified <code>pair</code>s&#47;<code>array</code>s seems unhelpful.  The BSI editorial
suggestion (UK-198/US-69,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2533.html">N2533</a>)
to merge <code>tuple</code> into <code>&lt;utility&gt;</code> would help with <code>pair</code>,
but not <code>array</code>.  That might be resolved by making a dependency between the
<code>&lt;array&gt;</code> header and <code>&lt;utility&gt;</code>, or simply recognising
the dependency be fulfilled in a Remark.
</p>

<p><i>[
2009-05-24 Daniel adds:
]</i></p>


<blockquote>
<p>
All <code>tuple_size</code> templates with a base class need to derive publicly, e.g.
</p>

<blockquote><pre>
template &lt;IdentityOf T&gt; class tuple_size&lt; const T &gt; :
   <ins>public</ins> tuple_size&lt;T&gt; {};
</pre></blockquote>

<p>
The same applies to the tuple_element class hierarchies.
</p>
<p>
What is actually meant with the comment
</p>
<blockquote><p>
this solution relies on 'metafunction forwarding' to inherit the
nested typename type
</p></blockquote>
<p>
?
</p>
<p>
I ask, because all base classes are currently unconstrained and their
instantiation is invalid in the constrained context of the <code>tuple_element</code> partial
template specializations.
</p>
</blockquote>

<p><i>[
2009-05-24 Alisdair adds:
]</i></p>


<blockquote>
<p>
I think a better solution might be to ask Pete editorially to change all
declarations of tupling APIs to use the struct specifier instead of class.
</p>
<p>
"metafunction forwarding" refers to the MPL metafunction protocol, where a
metafunction result is declared as a nested typedef with the name "type",
allowing metafunctions to be chained by means of inheritance.  It is a
neater syntax than repeatedly declaring a typedef, and inheritance syntax is
slightly nicer when it comes to additional typename keywords.
</p>
<p>
The constrained template with an unconstrained base is a good observation
though.
</p>
</blockquote>

<p><i>[
2009-10 post-Santa Cruz:
]</i></p>


<blockquote><p>
Move to Open, Alisdair to provide wording. Once wording is
provided, Howard will move to Review.
</p></blockquote>

<p><i>[
2010-03-28 Daniel deconceptified wording.
]</i></p>


<p><i>[
Post-Rapperswil - Daniel provides wording:
]</i></p>


<p>
The below given P&#47;R reflects the discussion from the Rapperswil meeting that the wording should not constrain 
implementation freedom to realize the actual issue target. Thus the original code form was replaced by
normative words.
</p>
<p>
While preparing this wording it turned out that several <code>tuple_size</code> specializations as 
that of <code>pair</code> and <code>array</code> are underspecified, because the underlying type of the member 
value is not specified except that it is an integral type. For the specializations we could introduce a 
canonical one - like <code>size_t</code> - or we could use the same type as the specialization of the 
unqualified type uses. The following wording follows the second approach.
</p>
<p>
The wording refers to N3126.
</p>

<blockquote><p>
Moved to Tentatively Ready after 6 positive votes on c++std-lib.
</p></blockquote>

<p><i>[
Adopted at 2010-11 Batavia
]</i></p>




<p id="res-1118"><b>Proposed resolution:</b></p>

<ol>
<li>Change 22.4.1 <a href="https://wg21.link/tuple.general">[tuple.general]</a> p.2, header <code>&lt;tuple&gt;</code> synopsis, as indicated:
<blockquote><pre>
// 20.4.2.5, tuple helper classes:
template &lt;class T&gt; class tuple_size; // undefined
<ins>template &lt;class T&gt; class tuple_size&lt;const T&gt;;</ins>
<ins>template &lt;class T&gt; class tuple_size&lt;volatile T&gt;;</ins>
<ins>template &lt;class T&gt; class tuple_size&lt;const volatile T&gt;;</ins>
<ins></ins>
template &lt;class... Types&gt; class tuple_size&lt;tuple&lt;Types...&gt; &gt;;
	
template &lt;size_t I, class T&gt; class tuple_element; // undefined
<ins>template &lt;size_t I, class T&gt; class tuple_element&lt;I, const T&gt;;</ins>
<ins>template &lt;size_t I, class T&gt; class tuple_element&lt;I, volatile T&gt;;</ins>
<ins>template &lt;size_t I, class T&gt; class tuple_element&lt;I, const volatile T&gt;;</ins>
<ins></ins>
template &lt;size_t I, class... Types&gt; class tuple_element&lt;I, tuple&lt;Types...&gt; &gt;;
</pre></blockquote>
</li>
<li>Add the end of subclause 22.4.7 <a href="https://wg21.link/tuple.helper">[tuple.helper]</a> insert the following two paragraphs:
<blockquote><pre>
<ins>template &lt;class T&gt; class tuple_size&lt;const T&gt;;</ins>
<ins>template &lt;class T&gt; class tuple_size&lt;volatile T&gt;;</ins>
<ins>template &lt;class T&gt; class tuple_size&lt;const volatile T&gt;;</ins>
</pre><blockquote><p>
<ins>Let <em>TS</em> denote <code>tuple_size&lt;T&gt;</code> of the <em>cv</em>-unqualified type <code>T</code>. 
Then each of the three templates shall meet the UnaryTypeTrait requirements (20.7.1) with a BaseCharacteristic of 
<code>integral_constant&lt;remove_cv&lt;decltype(<em>TS</em>::value)&gt;::type, <em>TS</em>::value&gt;</code>.</ins>
</p></blockquote></blockquote>

<blockquote><pre>
<ins>template &lt;size_t I, class T&gt; class tuple_element&lt;I, const T&gt;;</ins>
<ins>template &lt;size_t I, class T&gt; class tuple_element&lt;I, volatile T&gt;;</ins>
<ins>template &lt;size_t I, class T&gt; class tuple_element&lt;I, const volatile T&gt;;</ins>
</pre><blockquote><p>
<ins>Let <em>TE</em> denote <code>tuple_element&lt;I, T&gt;</code> of the <em>cv</em>-unqualified type <code>T</code>. Then each of the 
three templates shall meet the TransformationTrait requirements (20.7.1) with a member typedef <code>type</code> that shall name the 
same type as the following type:</ins></p>
<ul>
<li><ins>for the first specialization, the type <code>add_const&lt;<em>TE</em>::type&gt;::type</code>,</ins></li>
<li><ins>for the second specialization, the type <code>add_volatile&lt;<em>TE</em>::type&gt;::type</code>, and</ins></li>
<li><ins>for the third specialization, the type <code>add_cv&lt;<em>TE</em>::type&gt;::type</code></ins></li>
</ul>
</blockquote></blockquote>
</li>
</ol>






</body>
</html>
