<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
<title>A Unified Vision for Manipulating Tuple-like Objects</title>
<meta name="date" content="2016-03-18" />
<meta name="author" content="Matthew Woehlke (mwoehlke.floss&#64;gmail.com)" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="a-unified-vision-for-manipulating-tuple-like-objects">
<h1 class="title">A Unified Vision for Manipulating Tuple-like Objects</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">Document:</th><td class="field-body">P0311R0</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2016-03-18</td></tr>
<tr class="field"><th class="docinfo-name">Project:</th><td class="field-body">ISO/IEC JTC1 SC22 WG21 Programming Language C++</td>
</tr>
<tr class="field"><th class="docinfo-name">Audience:</th><td class="field-body">Evolution Working Group</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Matthew Woehlke (<a class="reference external" href="mailto:mwoehlke.floss&#64;gmail.com">mwoehlke.floss&#64;gmail.com</a>)</td></tr>
</tbody>
</table>
<style>
  html { color: black; background: white; }
  table.docinfo { margin: 2em 0; }
</style><div class="section" id="abstract">
<h1><a class="toc-backref" href="#id8">Abstract</a></h1>
<p>There is much activity and discussion surrounding tuple-like objects, with many features being requested and many papers submitted or planned. It is important that we establish a plan for where we are going that takes into account future directions in order to avoid overcomplicating the language or painting ourselves into a corner of incompatible features.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#abstract" id="id8">Abstract</a></li>
<li><a class="reference internal" href="#background" id="id9">Background</a></li>
<li><a class="reference internal" href="#preface" id="id10">Preface</a></li>
<li><a class="reference internal" href="#definitions" id="id11">Definitions</a></li>
<li><a class="reference internal" href="#access" id="id12">Access</a><ul>
<li><a class="reference internal" href="#an-operator-like-alternative" id="id13">An operator-like alternative</a></li>
</ul>
</li>
<li><a class="reference internal" href="#generalized-unpacking" id="id14">Generalized Unpacking</a></li>
<li><a class="reference internal" href="#unification-of-unpacking" id="id15">Unification of Unpacking</a></li>
<li><a class="reference internal" href="#slicing" id="id16">Slicing</a></li>
<li><a class="reference internal" href="#pack-generation-revisited" id="id17">Pack Generation, Revisited</a></li>
<li><a class="reference internal" href="#summary" id="id18">Summary</a></li>
<li><a class="reference internal" href="#acknowledgments" id="id19">Acknowledgments</a></li>
<li><a class="reference internal" href="#footnotes" id="id20">Footnotes</a></li>
<li><a class="reference internal" href="#references" id="id21">References</a></li>
</ul>
</div>
</div>
<div class="section" id="background">
<h1><a class="toc-backref" href="#id9">Background</a></h1>
<p>At the 2016 Jacksonville meeting, <a class="reference external" href="http://wg21.link/p0144">P0144</a> was discussed for the second time. Reception was generally positive, but some issues remained to be addressed. It seems quite clear that this is a desired direction for C++. Unfortunately, <a class="reference external" href="http://wg21.link/p0197">P0197</a>, which was scheduled for presentation and has some impact on the direction which <a class="reference external" href="http://wg21.link/p0144">P0144</a> is following, was skipped due to time constraints.</p>
<p>Discussion on the <tt class="docutils literal"><span class="pre">std-proposals</span></tt> forum often brings up the desire to extend use of &quot;tuple-like&quot; objects to contexts other than name binding (i.e. <a class="reference external" href="http://wg21.link/p0144">P0144</a>). There is also significant and related discussion on improving the usability of parameter packs. We feel that several of these areas are closely related and warrant the formation of a concrete and unified vision for future direction.</p>
</div>
<div class="section" id="preface">
<h1><a class="toc-backref" href="#id10">Preface</a></h1>
<p>We present several suggestions in this paper, along with accompanying syntax. We must stress <em>emphatically</em> that this paper is not intended to propose any features in and of itself (that will come later). Rather, we wish to outline several areas of anticipated future development which we feel need to be explored and, in particular, considered by other proposals being put forward, especially <a class="reference external" href="http://wg21.link/p0144">P0144</a>. While some brief statements are made as to our choices, we urge the reader to keep in mind that syntax shown is used in this context only as a tool to communicate examples of the future feature space, and not to get hung up on minor quibbles. In particular, our most immediate concern is for unification of implementation details related to unpacking and customization points of the same. While we feel also that similar considerations are important with respect to parameter packs, that feature space is less mature, and accordingly the need for a consolidated direction is less urgent, if no less real.</p>
</div>
<div class="section" id="definitions">
<h1><a class="toc-backref" href="#id11">Definitions</a></h1>
<p>A &quot;tuple like&quot; is any object consisting of one or (usually) more orthogonal values (in mathematical notation, a &quot;product type&quot;). The canonical example is <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">tuple</span></code>, but other examples include <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">array</span></code> or similar fixed-size vector types and most aggregates, as well as some non-aggregate user types including ones with no public NSDM's<a class="footnote-reference" href="#pt" id="id1">[1]</a>.</p>
<p>&quot;Unpacking&quot; refers to the conversion of a tuple-like object into its component parts. This includes both name-binding unpacking (i.e. <a class="reference external" href="http://wg21.link/p0144">P0144</a>) and &quot;generalized unpacking&quot; where the components are used in a non-binding context; for example, as values in a function parameter list. Name-binding unpacking is also called &quot;structured binding&quot; and, historically, &quot;assignment unpacking&quot;. We prefer the term &quot;name-binding unpacking&quot; as it does not call into question issues of &quot;true assignment&quot; versus aliasing where <a class="reference external" href="http://wg21.link/p0144">P0144</a> specifically desires to avoid certain overheads, and the use of &quot;unpacking&quot; serves to connect two closely related concepts.</p>
</div>
<div class="section" id="access">
<h1><a class="toc-backref" href="#id12">Access</a></h1>
<p>One of the active questions around <a class="reference external" href="http://wg21.link/p0144">P0144</a> regards the customization point. We feel strongly that the customization point for name-binding unpacking should be the same as used by generalized unpacking and by existing and proposed utility functions (e.g. <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">apply</span></code> and <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">make_from_tuple</span></code>) that act on tuple-like objects. This is important for the sake of consistency; these operations are extremely similar, and using different customization points will likely result in confusion and teaching difficulty.</p>
<p>That said, we feel less strongly about the exact nature of those customization points, providing that those points which are eventually used provide satisfactory backwards compatibility.</p>
<p>At present, these customization points are:</p>
<dl class="docutils">
<dt><code class="cpp c++"><span class="name">get</span><span class="operator">&lt;</span><span class="name">N</span><span class="operator">&gt;</span><span class="punctuation">(</span><span class="name">T</span><span class="punctuation">)</span></code>:</dt>
<dd>Access the N'th value of the tuple-like, where <code class="cpp c++"><span class="literal number integer">0</span> <span class="operator">&lt;</span> <span class="name">N</span> <span class="operator">&lt;</span> <span class="name">tuple_size</span><span class="punctuation">(</span><span class="name">T</span><span class="punctuation">)</span></code>.</dd>
<dt><code class="cpp c++"><span class="name">constexpr</span> <span class="name">tuple_size</span><span class="punctuation">(</span><span class="name">T</span><span class="punctuation">)</span></code>:</dt>
<dd>Returns the size of (i.e. number of elements in) the tuple-like.</dd>
</dl>
<div class="section" id="an-operator-like-alternative">
<h2><a class="toc-backref" href="#id13">An operator-like alternative</a></h2>
<p>Some concerns were expressed that overloading on <code class="cpp c++"><span class="name">get</span><span class="operator">&lt;</span><span class="name">N</span><span class="operator">&gt;</span><span class="punctuation">(</span><span class="name">T</span><span class="punctuation">)</span></code> is not appropriate due to its use for other operations that are not related to tuple-like objects. One alternative might be to implement a new operator type:</p>
<pre class="code c++ literal-block">
<span class="keyword">operator</span> <span class="name function">get</span><span class="punctuation">(</span><span class="keyword">auto</span><span class="operator">&amp;</span> <span class="name">tuple</span><span class="punctuation">,</span> <span class="name">constexpr</span> <span class="keyword type">size_t</span> <span class="name">i</span><span class="punctuation">);</span>
<span class="name">constexpr</span> <span class="keyword">operator</span> <span class="keyword">sizeof</span><span class="operator">&lt;</span><span class="name">T</span><span class="operator">&gt;</span><span class="punctuation">();</span>
</pre>
<p>It may be reasonable or even desirable to restrict access of these operators to either explicit spelling or use of dedicated syntax:</p>
<pre class="code c++ literal-block">
<span class="name">MyTupleLike</span> <span class="name">t</span><span class="punctuation">;</span>

<span class="punctuation">[</span><span class="literal number integer">0</span><span class="punctuation">]</span><span class="name">t</span><span class="punctuation">;</span> <span class="comment single">// operator get
</span><span class="keyword">sizeof</span><span class="punctuation">...(</span><span class="name">t</span><span class="punctuation">);</span> <span class="comment single">// operator sizeof
</span>
<span class="keyword">auto</span> <span class="punctuation">[</span><span class="name">x</span><span class="punctuation">,</span> <span class="name">y</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="name">t</span><span class="punctuation">;</span> <span class="comment single">// both, via name-binding unpacking, case 2
</span>
</pre>
<p>We should note that, while there are some strong feelings on these topics, we do not feel that any particular resolution is critical for any of the directions we are exploring. In this area, we feel only that a consistent and clear direction is important.</p>
<p>(Types have been elided in the above examples, as they are not crucial to the discussion.)</p>
</div>
</div>
<div class="section" id="generalized-unpacking">
<h1><a class="toc-backref" href="#id14">Generalized Unpacking</a></h1>
<p>Generalized unpacking is the conversion of a tuple-like to a &quot;value sequence&quot;, in the manner of Python's <tt class="docutils literal">*</tt> operator, such that the resulting sequence may be used in any place that a comma separated sequence may be used. While function parameter lists is the canonical example, this would also include braced initializer lists. Following <a class="reference external" href="https://groups.google.com/a/isocpp.org/d/msg/std-proposals/KW2FcaRAasc/Xc9lxRB1FwAJ">discussion</a> on the <tt class="docutils literal"><span class="pre">std-proposals</span></tt> forum, we believe that the most reasonable and useful mechanism of accomplishing this is to provide a mechanism whereby a tuple-like may be converted into a parameter pack. Much as in the name-binding unpacking case, there is a logical code transformation that can be applied for this purpose, by placing the tuple-like into a temporary (where necessary, i.e. if the tuple-like is an expression rather than already a named variable) and taking the parameter pack to be <code class="cpp c++"><span class="name">get</span><span class="operator">&lt;</span><span class="literal number integer">0</span><span class="operator">&gt;</span><span class="punctuation">(</span><span class="keyword type">__t</span><span class="punctuation">),</span> <span class="name">get</span><span class="operator">&lt;</span><span class="literal number integer">1</span><span class="operator">&gt;</span><span class="punctuation">(</span><span class="keyword type">__t</span><span class="punctuation">),</span> <span class="punctuation">...</span></code>. This extends the usable scope to anywhere a fold expression may be used.</p>
<p>We are aware of at least three possible mechanisms for implementing generalized unpacking. One option is to employ a new syntax to perform this operation directly. Another is to make multiple return values, treated as parameter packs, first class citizens of the language. A third is to create a parameter pack &quot;generator&quot;. The latter two options make it possible to write a function (which might reasonably be named <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">unpack</span></code>) that is equivalent to the former.</p>
<p>Several possible syntaxes have been proposed, including postfix operator <tt class="docutils literal">~</tt>. Our preference, however, is prefix operator <tt class="docutils literal">[:]</tt> (for reasons that will be — very briefly — shown later, in <a class="reference internal" href="#slicing">Slicing</a>), which we will use here, always bearing in mind that this is strictly for demonstrative purposes. For example:</p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="punctuation">{</span> <span class="keyword type">double</span> <span class="name">x</span><span class="punctuation">,</span> <span class="name">y</span><span class="punctuation">;</span> <span class="punctuation">}</span> <span class="name">point</span> <span class="operator">=</span> <span class="punctuation">...;</span>
<span class="keyword">auto</span> <span class="name">h</span> <span class="operator">=</span> <span class="name">std</span><span class="operator">::</span><span class="name">hypot</span><span class="punctuation">([</span><span class="operator">:</span><span class="punctuation">]</span><span class="name">point</span><span class="punctuation">...);</span>
</pre>
<p>The addition of such a feature, regardless of its form<a class="footnote-reference" href="#uf" id="id2">[2]</a>, would obviate most (though perhaps not all) use cases for <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">apply</span></code> and <code class="cpp c++"><span class="name">sd</span><span class="operator">::</span><span class="name">make_from_tuple</span></code>. It would also permit trivial conversions between different &quot;simple&quot; types which are distinct but layout compatible, by unpacking the first type into a braced initializer list used to construct the second. We believe that this feature will be at least as important and useful as name-binding unpacking.</p>
</div>
<div class="section" id="unification-of-unpacking">
<h1><a class="toc-backref" href="#id15">Unification of Unpacking</a></h1>
<p>Possibly the most important aspect of <a class="reference external" href="http://wg21.link/p0197">P0197</a> in our opinion is the provision for a single, unified mechanism for unpacking, whether in the name-binding or generalized senses. The critical aspect of <a class="reference external" href="http://wg21.link/p0197">P0197</a>, and the one that we feel strongly needs to be considered by <a class="reference external" href="http://wg21.link/p0144">P0144</a>, is providing implicit general tuple-like access to simple data structures. In particular, we feel that it would be a travesty for name-binding unpacking and generalized unpacking to use different customization points or to otherwise behave differently when used in ways where intuition strongly expects equivalent behavior. In particular, we feel strongly that, for a tuple-like type having a default destructor, the following should be equivalent (after optimizations):</p>
<pre class="code c++ literal-block">
<span class="keyword">auto</span> <span class="punctuation">[</span><span class="name">x</span><span class="punctuation">,</span> <span class="name">y</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="name">t</span><span class="punctuation">;</span>
<span class="keyword">auto</span> <span class="punctuation">[</span><span class="name">x</span><span class="punctuation">,</span> <span class="name">y</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="punctuation">{[</span><span class="operator">:</span><span class="punctuation">]</span><span class="name">t</span><span class="punctuation">...};</span>
</pre>
<p>(This illustrates a need to be careful with lifetime semantics; in particular, unpacking should likely either extend lifetime when used in a braced initializer list, or should explicitly create value copies in such case. The former would make the above equivalent for <em>any</em> tuple-like, while the latter may be useful for separating lifetime of the tuple-like and its components. We do not recommend a direction at this time, although this is likely to be of relevance when considering a language solution versus a &quot;library&quot; solution.)</p>
<p>It should be noted that <a class="reference external" href="http://wg21.link/p0197">P0197</a> would provide a modest enhancement to name-binding unpacking. Where <a class="reference external" href="http://wg21.link/p0144">P0144</a> limits itself to &quot;flat&quot; classes, <a class="reference external" href="http://wg21.link/p0197">P0197</a> would extend implicit tuple-like access to all classes which:</p>
<blockquote>
<ul class="simple">
<li>Contain no non-public NSDM's</li>
<li>Contain no members of union type</li>
<li>Have no virtual<a class="footnote-reference" href="#vb" id="id3">[3]</a> and/or non-public<a class="footnote-reference" href="#eb" id="id4">[4]</a> base classes</li>
<li>Have no base classes which do not also meet the preceding eligibility criteria</li>
</ul>
</blockquote>
<p>While it would not be a catastrophic loss if non-&quot;flat&quot; classes were not supported, we do feel that it would be most unfortunate if we are not able — eventually — to rely on this implicit access to implement name-binding unpacking, and accordingly to eliminate <a class="reference external" href="http://wg21.link/p0144">P0144</a> case 3. In addition to consistency, we feel that this is important for the sake of simplicity, as it eliminates a special case from name-binding unpacking. We are confident that the performance issues (that is, the understanding that case 3 represents name aliasing and neither consumes storage beyond that required for the tuple-like itself nor adds any access indirection) can be satisfactorily addressed through compiler optimization, keeping in mind of course that the implementations of the &quot;get&quot; function (however we ultimately spell it) are inline in these instances.</p>
<p>The problem that arises from this approach is bitfield members. At the 2016 Jacksonville meeting, at least one individual expressed a strong opinion that providing read/write access to bitfield members via name-binding unpacking is a &quot;must have&quot; feature. We encourage giving serious consideration to the true importance of this feature, and to ways that this could be addressed in a way that does not require special casing. (In particular, we note that the general ability to have a reference to a bitfield — likely through some new library type — seems at least as interesting as being able to name-bind to a component of such type of a tuple-like.)</p>
</div>
<div class="section" id="slicing">
<h1><a class="toc-backref" href="#id16">Slicing</a></h1>
<p>In our earlier discussion on <a class="reference internal" href="#access">Access</a>, we mentioned syntax for accessing specific elements of a tuple-like. While the need to access individual elements is obvious and clearly does not require a syntactic solution (we already have <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">get</span><span class="operator">&lt;</span><span class="name">N</span><span class="operator">&gt;</span></code>), another desire that comes up often is the ability to slice a tuple-like; e.g. to strip the first element or take only the first N elements.</p>
<p>We chose <code class="cpp c++"><span class="punctuation">[</span><span class="operator">:</span><span class="punctuation">]</span></code> because it naturally extends to slicing, but various possible solutions have been suggested, including pack generators (which would offer significant expressive power). More importantly, since we recommend that generalized unpacking convert a tuple-like to a parameter pack, it makes sense that a syntax for slicing tuple-likes should also work on parameter packs directly. In addition to the advantages for tuple-likes, this enables simple and powerful transformations for variadic templates, thus satisfying another important contemporary use case. In particular, we can now write recursive variadic template functions like:</p>
<pre class="code c++ literal-block">
<span class="keyword type">void</span> <span class="name function">print_each</span><span class="punctuation">()</span> <span class="punctuation">{}</span> <span class="comment single">// sentinel
</span>
<span class="keyword">template</span> <span class="operator">&lt;</span><span class="keyword">typename</span><span class="punctuation">...</span> <span class="name">T</span><span class="operator">&gt;</span>
<span class="keyword type">void</span> <span class="name">print_each</span><span class="punctuation">(</span><span class="name">T</span><span class="punctuation">...</span> <span class="name">values</span><span class="punctuation">)</span>
<span class="punctuation">{</span>
  <span class="name">print_one</span><span class="punctuation">([</span><span class="literal number integer">0</span><span class="punctuation">]</span><span class="name">values</span><span class="punctuation">);</span>
  <span class="name">print_each</span><span class="punctuation">([</span><span class="literal number integer">1</span><span class="operator">:</span><span class="punctuation">]</span><span class="name">values</span><span class="punctuation">);</span>
<span class="punctuation">}</span>
</pre>
<p>This is a fairly trivial example that previously could be written by breaking the complete pack into a separately named head argument and tail pack. This, however, merely scratches the surface. One could imagine implementing a <code class="cpp c++"><span class="name">constexpr</span></code> divide-and-conquer sort algorithm using slicing to trivially split the incoming parameter pack in half. Many other examples which can be readily implemented with slicing but would be difficult and/or expensive to implement otherwise can be imagined.</p>
</div>
<div class="section" id="pack-generation-revisited">
<h1><a class="toc-backref" href="#id17">Pack Generation, Revisited</a></h1>
<p>Parameter pack generation is, in general, an interesting feature. Suggested example uses include generating an integer list<a class="footnote-reference" href="#il" id="id5">[5]</a>, a type list, and performing various manipulations on parameter packs. While such manipulations could include slicing and reversing, we note that these operations appear to rely on a syntactic mechanism for extracting a single element from a pack (reference is made to <a class="reference external" href="http://wg21.link/n4235">N4235</a>). We also wonder if slicing operations implemented in this manner would perform satisfactorily compared to syntactic slicing.</p>
<p>Consequently, we still need a syntax for indexed access of parameter pack elements. This in turn allows us to apply the previous argument in reverse; namely, why not select a syntax that is non-ambiguous, easily extended to slicing, and may be applied also to tuple-likes? This is a point that we feel is worth serious consideration as we consider what direction generalized unpacking should take.</p>
</div>
<div class="section" id="summary">
<h1><a class="toc-backref" href="#id18">Summary</a></h1>
<p>Previous discussions — both in EWG and on the <tt class="docutils literal"><span class="pre">std-proposals</span></tt> forum — suggest a strong desire by the C++ community to move the language in a direction that blurs the line between containers and their contained value sequences, making it easy to move from one to the other, as is often found in other languages (e.g. Python). At the same time, there are a number of proposals either published or in the works to simplify working with parameter packs. Moreover, due to the significant utility of unpacking and otherwise working with tuple-like objects as parameter packs, these areas are closely related and to some extent overlap.</p>
<p>We have observed recently that &quot;complexity&quot; is a frequent complaint made against C++, especially that it is &quot;hard to teach&quot;. As we consider features to simplify working with tuple-like objects and/or parameter packs, we feel it is of utmost importance to establish and adhere to a consistent vision of these functions, in terms of both syntax and function. We specifically urge that name-binding unpacking would carefully consider customization points<a class="footnote-reference" href="#cp" id="id6">[6]</a> and the future possibility of implicit tuple-like access (see especially <a class="reference external" href="http://wg21.link/p0197">P0197</a>) and generalized unpacking in order to work toward<a class="footnote-reference" href="#fd" id="id7">[7]</a> a common mechanism for both that would eliminate special case rules specific to the individual features.
We also urge the committee to consider these issues and how such features relate (or can be made to relate) to tuple-like objects in order to maximize consistency of operations on both object types, and we urge authors working on such proposals to do likewise. Finally, we strongly encourage any authors working in this realm to maintain communication in order to reduce the dangers of competing, incompatible proposals and to maximize our ability as a community to pursue a well considered, consistent, and maximally functional direction.</p>
<p>By offering a glimpse at where we might be going, we hope we have demonstrated the importance of keeping the future in mind while developing new and exciting features today. We especially hope we have demonstrated the importance of considering the direction proposed by <a class="reference external" href="http://wg21.link/p0197">P0197</a> (implicit tuple-like access for &quot;simple&quot; types) in light of <a class="reference external" href="http://wg21.link/p0144">P0144</a> (name-binding unpacking) in order to maintain consistency and simplicity of specification in order to maximize the ability of users to understand the operation of these features and to use them in a sensible manner.</p>
</div>
<div class="section" id="acknowledgments">
<h1><a class="toc-backref" href="#id19">Acknowledgments</a></h1>
<p>We would like to thank the authors of <a class="reference external" href="http://wg21.link/p0144">P0144</a>, for obvious reasons. We would like to thank Mike Spertus and Daveed Vandevoorde for sharing a &quot;preview&quot; of their respective works-in-progress in the area of parameter packs. We would like to thanks Daniel Frey for his own work on parameter packs, which also forced us to consider the defense our own preferences more strenuously than had been done before. As always, we would also like to thank everyone that has shared their thoughts and ideas on these issues, both in person at the 2016 Jacksonville meeting and on <tt class="docutils literal"><span class="pre">std-proposals</span></tt>.</p>
</div>
<div class="section" id="footnotes">
<h1><a class="toc-backref" href="#id20">Footnotes</a></h1>
<table class="docutils footnote" frame="void" id="pt" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td><a class="reference external" href="http://doc.qt.io/qt-5.6/qvector3d.html">QVector3D</a> comes to mind as an example of a user type which is — or at least, ought to be — tuple-like but has no public data members.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="uf" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td>The form that unpacking takes is not entirely uninteresting, however such discussion is not in scope for this paper.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="vb" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3">[3]</a></td><td>While present in the initial revision of <a class="reference external" href="http://wg21.link/p0197">P0197</a>, this restriction is not seen in <a class="reference external" href="http://wg21.link/p0144">P0144</a>, and upon further consideration, may be unnecessary.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="eb" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id4">[4]</a></td><td>This could probably be relaxed to non-public <em>and non-empty</em> base classes, if desired.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="il" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id5">[5]</a></td><td>The purely template implementation of <code class="cpp c++"><span class="name">std</span><span class="operator">::</span><span class="name">integer_sequence</span></code> is extremely expensive, to the point that many compilers are providing implementations based on compiler intrinsics. Parameter pack generators have the potential to provide a satisfactory implementation without such intrinsics.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="cp" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id6">[6]</a></td><td>It is our understanding that the committee and the authors of <a class="reference external" href="http://wg21.link/p0144">P0144</a> are well aware of the strong feelings surrounding customization points and <em>are</em> giving them serious consideration. We wish to take this opportunity to thank and commend them for these efforts.</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="fd" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id7">[7]</a></td><td>We would like to reiterate that we have no objection to special case handling of &quot;implicitly tuple-like&quot; types in the short term, especially if it means name-binding unpacking is available in C++17, <em>provided</em> there is a long term migration route that would allow this special case to be replaced with more generalized functionality.</td></tr>
</tbody>
</table>
</div>
<div class="section" id="references">
<h1><a class="toc-backref" href="#id21">References</a></h1>
<ul>
<li><p class="first">(Discussion) std::invoke and unpacking tuple-like type instances</p>
<p><a class="reference external" href="https://groups.google.com/a/isocpp.org/d/msg/std-proposals/PghsmqN1cAw/0Q1V-22lFAAJ">https://groups.google.com/a/isocpp.org/d/msg/std-proposals/PghsmqN1cAw/0Q1V-22lFAAJ</a></p>
</li>
<li><p class="first">(Discussion) Unpacking tuples to value sequences</p>
<p><a class="reference external" href="https://groups.google.com/a/isocpp.org/d/msg/std-proposals/KW2FcaRAasc/Xc9lxRB1FwAJ">https://groups.google.com/a/isocpp.org/d/msg/std-proposals/KW2FcaRAasc/Xc9lxRB1FwAJ</a></p>
</li>
<li><p class="first">(Discussion) Extracting tuples out of a tuple</p>
<p><a class="reference external" href="https://groups.google.com/a/isocpp.org/d/msg/std-proposals/-81BeWT5DCA/Xs8uPY_zHgAJ">https://groups.google.com/a/isocpp.org/d/msg/std-proposals/-81BeWT5DCA/Xs8uPY_zHgAJ</a></p>
</li>
<li><p class="first">(Discussion) Improve fundamentals of parameter packs</p>
<p><a class="reference external" href="https://groups.google.com/a/isocpp.org/d/msg/std-proposals/ajLcDl8GbpA/woiAbredAwAJ">https://groups.google.com/a/isocpp.org/d/msg/std-proposals/ajLcDl8GbpA/woiAbredAwAJ</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/n4235">N4235</a> Selecting from Parameter Packs</p>
<p><a class="reference external" href="http://wg21.link/n4235">http://wg21.link/n4235</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0144">P0144</a> Structured Bindings</p>
<p><a class="reference external" href="http://wg21.link/p0144">http://wg21.link/p0144</a></p>
</li>
</ul>
<ul>
<li><p class="first"><a class="reference external" href="http://wg21.link/p0197">P0197</a> Default Tuple-like Access</p>
<p><a class="reference external" href="http://wg21.link/p0197">http://wg21.link/p0197</a></p>
</li>
</ul>
<!-- .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. -->
<!-- kate: hl reStructuredText -->
</div>
</div>
</body>
</html>
