<html>
<head>
<title>P0217R0: Wording for structured bindings</title>

<style type="text/css">
  ins { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .new { text-decoration:none; font-weight:bold; background-color:#D0FFD0 }
  .rule { background-color:#FFFF40 }
  .ex { background-color: #D0FFF0 }
  del { text-decoration:line-through; background-color:#FFA0A0 }  
  strong { font-weight: inherit; color: #2020ff }
</style>
</head>

<body>
P0217R0<br/>
Jens Maurer &lt;Jens.Maurer@gmx.net><br/>
Audience: Evolution and Core Working Groups<br/>
2016-02-10<br/>

<h1>P0217R0: Proposed wording for structured bindings</h1>

<h2>Introduction</h2>

This paper presents the proposed wording to implement structured
bindings as described by Herb Sutter, Bjarne Stroustrup, and Gabriel
dos Reis in P0144R1.

<h2>Wording</h2>

In section 6.5 [stmt.iter] paragraph 1, change the grammar to allow a
decomposition declaration:

<blockquote>
<pre>
<em>for-range-declaration:
      attribute-specifier-seq<sub>opt</sub> decl-specifier-seq declarator</em>
      <ins><em>attribute-specifier-seq</em><sub>opt</sub> <em>decl-specifier-seq</em> &<sub>opt</sub> { <em>identifier-list</em> }</ins>
</pre>
</blockquote>

In section 7 [dcl.dcl] paragraph 1, change the grammar to allow a
decomposition declaration:

<blockquote>
<pre>
<em>simple-declaration:
      decl-specifier-seq init-declarator-list<sub>opt</sub></em> ;
      <em>attribute-specifier-seq decl-specifier-seq init-declarator-list</em> ;
      <ins><em>attribute-specifier-seq</em><sub>opt</sub> <em>decl-specifier-seq</em> &<sub>opt</sub> { <em>identifier-list</em> } <em>brace-or-equal-initializer</em> ;</ins>
</pre>
</blockquote>

Add a new paragraph after 7 [dcl.dcl] paragraph 8:

<blockquote class="new">
A <em>simple-declaration</em> with an <em>identifier-list</em> is
called a <em>decomposition declaration</em>. The <em>decl-specifier-seq</em>
shall contain only the <em>type-specifier</em> <code>auto</code>
(7.1.6.4 [dcl.spec.auto]) and <em>cv-qualifier</em>s.  The
<em>brace-or-equal-initializer</em> shall be of the form "=
<em>assignment-expression</em>" or of the form "{
<em>assignment-expression</em> }".  If the
<em>assignment-expression</em> is a prvalue, the
<em>decl-specifier-seq</em> does not contain the <em>cv-qualifier</em>
<code>const</code>, and <code>&</code> follows the
<em>decl-specifier-seq</em>, the program is ill-formed.

</blockquote>

Add after 7.1.6.4 [dcl.spec.auto] paragraph 8:

<blockquote class="new">
A decomposition declaration introduces the <em>identifier</em>s of the
<em>identifier-list</em> as variable names in the order of appearance,
with types deduced from the initializer.  If the
<em>assignment-expression</em> of the decomposition declaration has
scalar type, the <em>identifier-list</em> shall contain a single
<em>identifier</em> and a single variable is introduced as if by

<pre>
  <em><em>attribute-specifier-seq</em><sub>opt</sub> decl-specifier-seq</em> &<sub>opt</sub> <em>identifier</em> <em>brace-or-equal-initializer</em> ;
</pre>

If the <em>assignment-expression</em> has union type, the program is
ill-formed.
<p>

Otherwise, i.e. the <em>assignment-expression</em> has non-union class
or array type <code>E</code>, let <em>e</em> be a
glvalue of type <code>E</code>.

<ul>

<li>If the <em>assignment-expression</em> is a prvalue, <em>e</em>
is an xvalue that designates a temporary object
copy-initialized from the <em>assignment-expression</em>.  The
lifetime of the temporary ends immediately after the last variable
declaration (see below) if no <code>&</code> follows the
<em>decl-specifier-seq</em> in the decomposition declaration, and is
extended as usual (12.2 [class.temporary] otherwise.</li>

<li>Otherwise, <em>e</em> refers to the result of evaluating the
<em>assignment-expression</em> and has its value
category.</li>

</ul>

The expression <em>get<sub>n</sub></em> is defined as follows:

<ul>
<li>If E is an array type, <em>get<sub>n</sub></em> is
<em>e</em>[<em>n</em>].

<li>If E is a class type, the <em>unqualified-id</em>
<code>get</code> is looked up in the scope of E as if by class member
access lookup (3.4.5 [basic.lookup.classref]), and if that finds at
least one declaration, <em>get<sub>n</sub></em> is
<code><em>e</em>.get&lt;<em>n</em>>()</code>.</li>

<li>Otherwise, <em>get<sub>n</sub></em> is
<code>get&lt;<em>n</em>>(<em>e</em>)</code>, where <code>get</code> is
looked up in the associated namespaces (3.4.2
[basic.lookup.argdep]). [ Note: Ordinary unqualified lookup (3.4.1
[basic.lookup.unqual]) is not performed. -- end note ]</li>

</ul>



If <code>E</code> is an array type, the number of <em>identifier</em>s
shall be equal to the number of elements of <code>E</code>.
Otherwise, if the expression <em>get<sub>0</sub></em> is not
well-formed, all of <code>E</code>'s non-static data members and
bit-fields shall be public direct members of <code>E</code> or of the
same public base class of <code>E</code>, <code>E</code> shall not
have an anonymous union member, and the number of <em>identifier</em>s
in the <em>identifier-list</em> shall be equal to the number of
non-static data members of <code>E</code>.
<p>

For the <em>i</em>-th <em>identifier</em> <em>v<sub>i</sub></em> in
the <em>identifier-list</em>, where numbering starts at 1, a variable
is declared using the <em>attribute-specifier-seq</em> and
<em>decl-specifier-seq</em> from the decomposition declaration, and a
<em>declarator</em> <code>&<sub>opt</sub></code>
<em>v<sub>i</sub></em> , where <code>&</code> is present if and only
if it is present in the decomposition declaration.  If the
expression <em>get<sub>0</sub></em> is well-formed, the
variable is initialized with the expression
<em>get<sub>i-1</sub></em>, otherwise it is
initialized with the expression <em>e</em>.<em>m<sub>i</sub></em> ,
where <em>m<sub>i</sub></em> designates the <em>i</em>-th non-static
data member of <code>E</code>.  The variable is copy-initialized or
direct-initialized as indicated by the form of the
<em>brace-or-equal-initializer</em> (8.5 [dcl.init]).

[ Note: The type of <em>v<sub>i</sub></em> is deduced from its
initializer as described in the remainder of this section. -- end note ]
</li>

[ Example:
<pre>
struct S { int x; volatile double y; };
const S f();
auto { x, y } = f();
</pre>

The type of x is "int", the type of y is "double". -- end example ]

</blockquote>


</body>
</html>
