Topic: Structured Bindings for all the Aggregates
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Thu, 13 Oct 2016 05:16:42 -0700 (PDT)
Raw View
------=_Part_747_1169429215.1476361002381
Content-Type: multipart/alternative;
boundary="----=_Part_748_210024893.1476361002381"
------=_Part_748_210024893.1476361002381
Content-Type: text/plain; charset=UTF-8
We believe that there's a gap in coverage between what kinds of types you
can decompose with structured bindings, now that we have extended the
concept of aggregate. We also believe that the kind of scaffolding
necessary to support structured bindings could be extended to be useful in
other contexts - at the very least std::apply() but also any other
metaprogramming. This proposal attempts to bridge all those gaps.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dd89a60a-5bc2-4560-9343-212dcbf56cb1%40isocpp.org.
------=_Part_748_210024893.1476361002381
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">We believe that there's a gap in coverage between what=
kinds of types you can decompose with structured bindings, now that we hav=
e extended the concept of aggregate. We also believe that the kind of scaff=
olding necessary to support structured bindings could be extended to be use=
ful in other contexts - at the very least std::apply() but also any other m=
etaprogramming. This proposal attempts to bridge all those gaps.=C2=A0</div=
>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/dd89a60a-5bc2-4560-9343-212dcbf56cb1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dd89a60a-5bc2-4560-9343-212dcbf56cb1=
%40isocpp.org</a>.<br />
------=_Part_748_210024893.1476361002381--
------=_Part_747_1169429215.1476361002381
Content-Type: text/html; charset=US-ASCII; name=tuple_like.html
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=tuple_like.html
X-Attachment-Id: e355958e-d87a-4f01-b271-6f4741640474
Content-ID: <e355958e-d87a-4f01-b271-6f4741640474>
<html>
<head>
<title>tuple-like</title>
<style>
p {text-align:justify}
li {text-align:justify}
blockquote.note
{
background-color:#E0E0E0;
padding-left: 15px;
padding-right: 15px;
padding-top: 1px;
padding-bottom: 1px;
}
ins {color:#00A000}
del {color:#A00000}
code {white-space:pre;}
</style>
</head>
<body>
<address align=right>
Document number: DxxxxR0<br/>
<a href="mailto:barry.revzin@gmail.com">Barry Revzin</a><br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a></br>
2016-10-12<br/>
</address>
<hr/>
<h1 align=center>Filling the gaps between structured bindings and aggregates</h1>
<h2>Contents</h2>
<ul>
<li><a href="#Motivation">Motivation</a></li>
<li><a href="#Proposal">Proposal</a></li>
<li><a href="#Examples">Examples</a></li>
</ul>
<a name="Motivation"></a><h2>Motivation</h2>
<p>Recently, we have extended the concept of aggregates to include types with public base classes <sup><a href="#fn1" id="ref1">[1]</a></sup>. We have separately added support for structured bindings <sup><a href="#fn2" id="ref2">[2]</a></sup>. But there exists some drift between the two language features - structured bindings work on a subset of aggregates in a way that is inconsistent with the intent of either feature:
<blockquote><pre>
struct A { int x, y; };
A a{1, 2}; // ok since C++11
auto [x, y] = a; // ok in C++17
struct B { int x; };
struct C : B { int y; };
C c{1, 2}; // ok in C++17
auto [x,y] = c; // error
</pre></blockquote>
Moreover, structured bindings introduce inconsistencies between types we can decompose manually and types we can decompose automatically with template metaprogramming. That is, we can manually decompose a subset of aggregates as well as <code>std::pair</code>s and <code>std::tuple</code>s out of the box with structured bindings. But we can't pass aggregates into other library functions that use conceptually similar machinery, like <code>std::apply</code>:
<blockquote><pre>
void foo(int, int );
// manually unpacking works
auto [x,y] = std::make_tuple(1, 2);
foo(x, y);
// unpacking metaprogrammatically works
std::apply(foo, std::make_tuple(1, 2));
struct A { int x, y; };
// unpacking manually works
auto [x,y] = A{1, 2};
foo(x, y);
// but not metaprogrammatically!?
std::apply(foo, A{1,2}); // error
</pre></blockquote>
Additionally, raw arrays continue to be left behind:
<blockquote><pre>
int raw[2];
std::get<0>(raw) = 42; // error
auto size = std::tuple_size<decltype(raw)>::value; // error
std::array<int, 2> modern;
std::get<0>(modern) = 42; // ok
auto size = std::tuple_size<decltype(modern)>::value; // ok, size == 2
</pre></blockquote>
<p>We feel that these inconsistencies make these features far less useful than they could, and should, be.
<a name="Proposal"></a><h2>Proposal</h2>
<p>Building on P0197<sup><a href="#fn3" id="ref1">[3]</a></sup>, we would like to introduce the concept of a <i>tuple-like</i> type to be a type on which we can invoke the metafunction <code>std::tuple_size</code> to determine a number of elements and, for each valid index, get each element via <code>std::get</code>. At the moment, the tuple-like types provided by the standard are <code>std::pair</code>, <code>std::tuple</code>, and <code>std::array</code>. But we would like to enlarge the universe of tuple-like types to include, out of the box, all aggregates.
<p>For raw arrays, we introduce the template specializations:
<blockquote><pre>
template <class T, size_t N>
struct tuple_size<T[N]> : std::integral_constant<size_t, N> { };
template <<size_t Idx, class T, size_t N>
constexpr T& get(T (&array)[N]) {
static_assert(Idx < N);
return array[Idx];
}
</pre></blockquote>
For aggregates of class type <code>T</code>, to instantiate the class template <code>std::tuple_size<T></code>, if no prior specialization can be found, synthesize a new specialization which inherits from <code>std::integral_constant<size_t, N></code>, where <code>N</code> is the number of non-static data members. Similarly, to instantiate the function template <code>std::get<N>(T)</code>, if no overload can be found, synthesize a new overload which returns the <code>N</code>th non-static data member.
<p>There are currently three cases for structured bindings: arrays, tuple-like types as defined in this paper, and a subset of aggregates. We can reduce this to just the one.
<a name="Examples"></a><h2>Examples</h2>
With the new definition of tuple-like and the implicit synthesize of <code>tuple_size</code> and <code>get</code> for all aggregates, the following all just works:
<blockquote><pre>
struct A { int i; char c; };
struct B : A { double d; };
static_assert(tuple_size<A>{} == 2);
static_assert(tuple_size<B>{} == 3);
// picking elements
A a{22, 'w'};
int first = std::get<0>(a);
char second = std::get<1>(a);
assert(first == 22 && second = 'w');
// decomposing aggregates
auto [i,c,d] = B{42, 'x', 3.14};
// applying aggregates
auto first = [](auto&& x, auto&&... ) { return x; }
int x = std::apply(first, A{17, 'j'});
assert(x == 17);
// tuple-like array operations
int raw[3]{1, 2, 3};
int y = std::apply(first, raw);
assert(y == 1);
int z = std::get<2>(raw);
assert(z == 3);
int j = std::get<4>(raw); // error: bounds
// tuple_cat all the things
int others[2]{4, 5};
std::tuple<int,int,int,int,int,int,char> everything = std::tuple_cat(raw, others, a);
</pre></blockquote>
<p>
<span id="fn1">[1] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html">Extension to aggregate initialization (P00171R1)</a></span>
<p><span id="fn2">[2] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0217r3.html">Proposed wording for structured bindings (P0217R3)</a></span>
<p><span id="fn3">[3] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0197r0.pdf">Default Tuple-like Access (P0197R0)</a></span>
</body>
</html>
------=_Part_747_1169429215.1476361002381--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 13 Oct 2016 06:59:47 -0700 (PDT)
Raw View
------=_Part_323_298917959.1476367187829
Content-Type: multipart/alternative;
boundary="----=_Part_324_985432883.1476367187829"
------=_Part_324_985432883.1476367187829
Content-Type: text/plain; charset=UTF-8
I saw this in your motivation section:
struct B { int x; };
struct C : B { int y; };
C c{1, 2}; // ok in C++17
That does work, but it only works because of the use of brace elision. The
initializer ought to be `C c{{1}, 2};`, but C++ allows us to elide the
brace for an aggregate.
Structured binding should not use brace elision. Why? Because of the types.
If you do `auto [a, b] = c;`, what type is `a`? By all rights, that type is
`B`: the type of the first base class of `A`. But the user who initialized
`C` used `1`, which is an integer.
Brace elision allows an inference on the input side that structured binding
has no equivalent of. There has to be an inconsistency between the input
and the output. The input will be more lenient, using implicit methods to
fill in the blanks if you don't provide exactly the right thing.
Structured binding should not automatically *flatten* an aggregate that
contains other aggregates.
As for the rest, there have already been discussions about permitting the
tuple machinery to automatically introspect anything which structured
binding would work on. But this is not a hole in structured binding itself.
After all, tuple_element and tuple_size are all C++11 features. Structured
binding simply keys off of the existing machinery.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d525f68a-6019-410c-a477-0589492e5605%40isocpp.org.
------=_Part_324_985432883.1476367187829
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I saw this in your motivation section:<br><br><div style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> B </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> C </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> B </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br>C c</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// ok in C++17</span></div></code></div><br>That does work, but i=
t only works because of the use of brace elision. The initializer ought to =
be `C c{{1}, 2};`, but C++ allows us to elide the brace for an aggregate.<b=
r><br>Structured binding should not use brace elision. Why? Because of the =
types.<br><br>If you do `auto [a, b] =3D c;`, what type is `a`? By all righ=
ts, that type is `B`: the type of the first base class of `A`. But the user=
who initialized `C` used `1`, which is an integer.<br><br>Brace elision al=
lows an inference on the input side that structured binding has no equivale=
nt of. There has to be an inconsistency between the input and the output. T=
he input will be more lenient, using implicit methods to fill in the blanks=
if you don't provide exactly the right thing.<br><br>Structured bindin=
g should not automatically <i>flatten</i> an aggregate that contains other =
aggregates.<br><br>As for the rest, there have already been discussions abo=
ut permitting the tuple machinery to automatically introspect anything whic=
h structured binding would work on. But this is not a hole in structured bi=
nding itself. After all, tuple_element and tuple_size are all C++11 feature=
s. Structured binding simply keys off of the existing machinery.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d525f68a-6019-410c-a477-0589492e5605%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d525f68a-6019-410c-a477-0589492e5605=
%40isocpp.org</a>.<br />
------=_Part_324_985432883.1476367187829--
------=_Part_323_298917959.1476367187829--
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Thu, 13 Oct 2016 07:18:41 -0700 (PDT)
Raw View
------=_Part_781_1398402711.1476368321443
Content-Type: multipart/alternative;
boundary="----=_Part_782_883042103.1476368321444"
------=_Part_782_883042103.1476368321444
Content-Type: text/plain; charset=UTF-8
On Thursday, October 13, 2016 at 8:59:47 AM UTC-5, Nicol Bolas wrote:
>
>
> struct B { int x; };
> struct C : B { int y; };
>
> C c{1, 2}; // ok in C++17
>
> That does work, but it only works because of the use of brace elision. The
> initializer ought to be `C c{{1}, 2};`, but C++ allows us to elide the
> brace for an aggregate.
>
Right, because C conceptually is just a thing that has two named ints.
> Structured binding should not automatically *flatten* an aggregate that
> contains other aggregates.
>
We already do this today:
struct empty { };
struct S : empty { int x, y; };
S s{1,2};
auto [x,y] = s;
S contains another aggregate, but we don't have to write:
auto [e,x,y] = s;
Getting all the individual members seems a lot more useful than just
getting the base subobject(s), and then potentially re-getting those base
subobjects' members. Plus if I wanted C to have a B to be decomposable
into, I could always have written it as:
struct C2 {
B b;
int y;
};
I think C2 and C are meaningfully different types, so it makes sense for
them to be decomposed in different ways.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b9857870-f0ff-4374-9f23-ead74e107c1b%40isocpp.org.
------=_Part_782_883042103.1476368321444
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Thursday, October 13, 2016 at 8:59:47 AM UTC-5,=
Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px"><code><div><span style=3D=
"color:#008">struct</span><span style=3D"color:#000"> B </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">int</span><span style=3D"color:#000"> x</span><span style=3D"col=
or:#660">;</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">};</span><span style=3D"color:#000"><br></span><span style=3D"color:#00=
8">struct</span><span style=3D"color:#000"> C </span><span style=3D"color:#=
660">:</span><span style=3D"color:#000"> B </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">int=
</span><span style=3D"color:#000"> y</span><span style=3D"color:#660">;</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><=
span style=3D"color:#000"><br><br>C c</span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#066">1</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> </span><span style=3D"color:#066">2</span><span =
style=3D"color:#660">};</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=
=A0</span><span style=3D"color:#800">// ok in C++17</span></div></code></di=
v><br>That does work, but it only works because of the use of brace elision=
.. The initializer ought to be `C c{{1}, 2};`, but C++ allows us to elide th=
e brace for an aggregate.<br></div></blockquote><div><br></div><div>Right, =
because C conceptually is just a thing that has two named ints.=C2=A0</div>=
<div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">Structured binding should not automatically <i>flatten</i> an aggregate=
that contains other aggregates.<br></div></blockquote><div><br></div><div>=
We already do this today:</div><div><br></div><div><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> empty </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> S =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> empty </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>S s</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><font color=3D=
"#006666"><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #066;" class=3D"styled-by-prettify">2</span></font><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">[</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">y</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">]</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><font color=3D"#000000"><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> s</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span></font></div></cod=
e></div><br>S contains another aggregate, but we don't have to write:</=
div><div><br></div><div><div class=3D"prettyprint" style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><font color=3D"#660066"><span style=3D"color: =
#008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">[</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">e</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">y</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">]</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> s</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span></font></div></code></div><br></div><div>Getting all the i=
ndividual members seems a lot more useful than just getting the base subobj=
ect(s), and then potentially re-getting those base subobjects' members.=
Plus if I wanted C to have a B to be decomposable into, I could always hav=
e written it as:<br></div><div><br></div><div><div class=3D"prettyprint" st=
yle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 18=
7); border-style: solid; border-width: 1px; word-wrap: break-word;"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><font color=3D"#660066">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> C2 </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 B b</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></font></div></code></div><br>I think C2 and C are me=
aningfully different types, so it makes sense for them to be decomposed in =
different ways.=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b9857870-f0ff-4374-9f23-ead74e107c1b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b9857870-f0ff-4374-9f23-ead74e107c1b=
%40isocpp.org</a>.<br />
------=_Part_782_883042103.1476368321444--
------=_Part_781_1398402711.1476368321443--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 13 Oct 2016 07:36:20 -0700 (PDT)
Raw View
------=_Part_479_3944412.1476369381032
Content-Type: multipart/alternative;
boundary="----=_Part_480_262356679.1476369381033"
------=_Part_480_262356679.1476369381033
Content-Type: text/plain; charset=UTF-8
On Thursday, October 13, 2016 at 10:18:41 AM UTC-4, Barry Revzin wrote:
>
> On Thursday, October 13, 2016 at 8:59:47 AM UTC-5, Nicol Bolas wrote:
>>
>>
>> struct B { int x; };
>> struct C : B { int y; };
>>
>> C c{1, 2}; // ok in C++17
>>
>> That does work, but it only works because of the use of brace elision.
>> The initializer ought to be `C c{{1}, 2};`, but C++ allows us to elide the
>> brace for an aggregate.
>>
>
> Right, because C conceptually is just a thing that has two named ints.
>
If you made `B` have two ints, `C c{1, 2};` would *still work*. And that
`2` would go into `y`, not the second variable of `B`. The first element is
always the initializer of the base class, whether it's a single value or a
braced-init-list.
Brace elision is not about flattening `C`.
Structured binding should not automatically *flatten* an aggregate that
>> contains other aggregates.
>>
>
> We already do this today:
>
> struct empty { };
> struct S : empty { int x, y; };
>
> S s{1,2};
> auto [x,y] = s;
>
> S contains another aggregate, but we don't have to write:
>
> auto [e,x,y] = s;
>
>
And now you're explaining exactly why SB is not the inverse of aggregate
initialization.
AI would *require* you to specify an initializer for `empty`. SB does not.
SB is all about public member variables; AI is about initializing
aggregates of values.
They are not inverse operations. Therefore, they are not meant or expected
to look the same.
SB does not flatten anything. It simply looks at public members of a type.
> Getting all the individual members seems a lot more useful than just
> getting the base subobject(s), and then potentially re-getting those base
> subobjects' members. Plus if I wanted C to have a B to be decomposable
> into, I could always have written it as:
>
> struct C2 {
> B b;
> int y;
> };
>
> I think C2 and C are meaningfully different types, so it makes sense for
> them to be decomposed in different ways.
>
And yet, C2 and C will not be different in terms of aggregate
initialization. Your whole premise is that SB should work like the reverse
of AI.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c6bc1b94-c575-4552-b52d-069fbe607016%40isocpp.org.
------=_Part_480_262356679.1476369381033
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, October 13, 2016 at 10:18:41 AM UTC-4, Barry =
Revzin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
On Thursday, October 13, 2016 at 8:59:47 AM UTC-5, Nicol Bolas wrote:<block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px"><code><div><span style=3D"color:#008">struct</span><spa=
n style=3D"color:#000"> B </span><span style=3D"color:#660">{</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">int</span><span styl=
e=3D"color:#000"> x</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">};</span><span style=3D"col=
or:#000"><br></span><span style=3D"color:#008">struct</span><span style=3D"=
color:#000"> C </span><span style=3D"color:#660">:</span><span style=3D"col=
or:#000"> B </span><span style=3D"color:#660">{</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">int</span><span style=3D"color:#00=
0"> y</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><=
br>C c</span><span style=3D"color:#660">{</span><span style=3D"color:#066">=
1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#066">2</span><span style=3D"color:#660">};</span><=
span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:=
#800">// ok in C++17</span></div></code></div><br>That does work, but it on=
ly works because of the use of brace elision. The initializer ought to be `=
C c{{1}, 2};`, but C++ allows us to elide the brace for an aggregate.<br></=
div></blockquote><div><br></div><div>Right, because C conceptually is just =
a thing that has two named ints.</div></div></blockquote><div><br>If you ma=
de `B` have two ints, `C c{1, 2};` would <i>still work</i>. And that `2` wo=
uld go into `y`, not the second variable of `B`. The first element is alway=
s the initializer of the base class, whether it's a single value or a b=
raced-init-list.<br><br>Brace elision is not about flattening `C`.<br><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Structured binding should =
not automatically <i>flatten</i> an aggregate that contains other aggregate=
s.<br></div></blockquote><div><br></div><div>We already do this today:=C2=
=A0</div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div><br></div><div><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;w=
ord-wrap:break-word"><code><div><span style=3D"color:#008">struct</span><sp=
an style=3D"color:#000"> empty </span><span style=3D"color:#660">{</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">};</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">struct</span><sp=
an style=3D"color:#000"> S </span><span style=3D"color:#660">:</span><span =
style=3D"color:#000"> empty </span><span style=3D"color:#660">{</span><span=
style=3D"color:#000"> </span><span style=3D"color:#008">int</span><span st=
yle=3D"color:#000"> x</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> y</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">};</span><span style=3D"colo=
r:#000"><br><br>S s</span><span style=3D"color:#660">{</span><font color=3D=
"#006666"><span style=3D"color:#066">1</span><span style=3D"color:#660">,</=
span><span style=3D"color:#066">2</span></font><span style=3D"color:#660">}=
;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">au=
to</span><span style=3D"color:#000"> </span><span style=3D"color:#660">[</s=
pan><span style=3D"color:#000">x</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000">y</span><span style=3D"color:#660">]</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><font col=
or=3D"#000000"><span style=3D"color:#000"> s</span><span style=3D"color:#66=
0">;</span></font></div></code></div><br>S contains another aggregate, but =
we don't have to write:</div><div><br></div><div><div style=3D"backgrou=
nd-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;=
border-width:1px;word-wrap:break-word"><code><div><font color=3D"#660066"><=
span style=3D"color:#008">auto</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">[</span><span style=3D"color:#000">e</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000">x</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000">y</span><span style=3D"c=
olor:#660">]</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">=3D</span><span style=3D"color:#000"> s</span><span style=3D"color:#6=
60">;</span></font></div></code></div><br></div></div></blockquote><div><br=
>And now you're explaining exactly why SB is not the inverse of aggrega=
te initialization.<br><br>AI would <i>require</i> you to specify an initial=
izer for `empty`. SB does not. SB is all about public member variables; AI =
is about initializing aggregates of values.<br><br>They are not inverse ope=
rations. Therefore, they are not meant or expected to look the same.<br><br=
>SB does not flatten anything. It simply looks at public members of a type.=
<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div></div><div>Getting all the individual members seems a lot more usef=
ul than just getting the base subobject(s), and then potentially re-getting=
those base subobjects' members. Plus if I wanted C to have a B to be d=
ecomposable into, I could always have written it as:<br></div><div><br></di=
v><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187=
,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><=
div><font color=3D"#660066"><span style=3D"color:#008">struct</span><span s=
tyle=3D"color:#000"> C2 </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>=C2=A0 =C2=A0 B b</span><span style=3D"color:#660">;<=
/span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#008">int</span><span style=3D"color:#000"> y</span><span style=3D"colo=
r:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#660">};</span><span style=3D"color:#000"><br></span></font></div></code></=
div><br>I think C2 and C are meaningfully different types, so it makes sens=
e for them to be decomposed in different ways.</div></div></blockquote><div=
><br>And yet, C2 and C will not be different in terms of aggregate initiali=
zation. Your whole premise is that SB should work like the reverse of AI. <=
br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c6bc1b94-c575-4552-b52d-069fbe607016%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c6bc1b94-c575-4552-b52d-069fbe607016=
%40isocpp.org</a>.<br />
------=_Part_480_262356679.1476369381033--
------=_Part_479_3944412.1476369381032--
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Thu, 13 Oct 2016 08:14:11 -0700 (PDT)
Raw View
------=_Part_842_1501298747.1476371651356
Content-Type: multipart/alternative;
boundary="----=_Part_843_1365997211.1476371651356"
------=_Part_843_1365997211.1476371651356
Content-Type: text/plain; charset=UTF-8
>
>
> SB does not flatten anything. It simply looks at public members of a type.
> [...]
> And yet, C2 and C will not be different in terms of aggregate
> initialization. Your whole premise is that SB should work like the reverse
> of AI.
>
Maybe I misworded the original proposal, but our premise isn't that SB and
AI should be inverses. The premise is that an aggregate is just a
collection of values - whether those values are all in one type directly or
not. SB should be able to unpack an aggregate into all of its underlying
values - which would be all the public members, not the base class
subobjects. So yes, I agree that C and C2 would both be
aggregate-initializable with two ints, but C really has two int members so
it should unpack into two ints - whereas C2 has a B and an int and should
unpack in those.
Basically, we want that first sentence I quoted off of you to be true
regardless of if the public members of a type are all direct members of the
same type or not.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/db3d6f92-531b-416a-b58d-1e7ed8185ef3%40isocpp.org.
------=_Part_843_1365997211.1476371651356
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><br>SB does not flatten anything. It simply looks at public member=
s of a type. [...]</div><div>And yet, C2 and C will not be different in ter=
ms of aggregate initialization. Your whole premise is that SB should work l=
ike the reverse of AI. <br></div></div></blockquote><div><br></div><div>May=
be I misworded the original proposal, but our premise isn't that SB and=
AI should be inverses. The premise is that an aggregate is just a collecti=
on of values - whether those values are all in one type directly or not. SB=
should be able to unpack an aggregate into all of its underlying values - =
which would be all the public members, not the base class subobjects. So ye=
s, I agree that C and C2 would both be aggregate-initializable with two int=
s, but C really has two int members so it should unpack into two ints - whe=
reas C2 has a B and an int and should unpack in those.=C2=A0=C2=A0</div><di=
v><br></div><div>Basically, we want that first sentence I quoted off of you=
to be true regardless of if the public members of a type are all direct me=
mbers of the same type or not.=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/db3d6f92-531b-416a-b58d-1e7ed8185ef3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/db3d6f92-531b-416a-b58d-1e7ed8185ef3=
%40isocpp.org</a>.<br />
------=_Part_843_1365997211.1476371651356--
------=_Part_842_1501298747.1476371651356--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 13 Oct 2016 09:28:28 -0700 (PDT)
Raw View
------=_Part_457_702746525.1476376108187
Content-Type: multipart/alternative;
boundary="----=_Part_458_1247808455.1476376108187"
------=_Part_458_1247808455.1476376108187
Content-Type: text/plain; charset=UTF-8
On Thursday, October 13, 2016 at 11:14:11 AM UTC-4, Barry Revzin wrote:
>
> SB does not flatten anything. It simply looks at public members of a type.
>> [...]
>> And yet, C2 and C will not be different in terms of aggregate
>> initialization. Your whole premise is that SB should work like the reverse
>> of AI.
>>
>
> Maybe I misworded the original proposal, but our premise isn't that SB and
> AI should be inverses. The premise is that an aggregate is just a
> collection of values - whether those values are all in one type directly or
> not.
>
This premise is not supported by the C++ standard's definition for
"aggregate". An aggregate is a collection of *objects*, not of values. And
the subobjects in an aggregate may themselves have subobjects. "whether
those values are all in one type directly or not" is not something the C++
standard dismisses. The arrangement of objects in an aggregate *matters*,
not just in their order, but in which subobjects they are members of.
Aggregates are not flat in C++, and nothing in the standard has ever made
them so.
SB should be able to unpack an aggregate into all of its underlying values
> - which would be all the public members, not the base class subobjects. So
> yes, I agree that C and C2 would both be aggregate-initializable with two
> ints, but C really has two int members so it should unpack into two ints -
> whereas C2 has a B and an int and should unpack in those.
>
And you're explaining exactly why SB doesn't do this.
You believe that a base class member should be treated as if it were a
direct member of the derived class. I believe otherwise. The standard's
aggregate rules don't agree with you either. As such, one user will expect
SB to unpack the "underlying values", while another user will expect SB to
unpack the *subobjects* in the type.
By forbidding this case entirely, the standard ensures that there is no
confusion.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cda97908-314b-4ff6-aba7-c67f92b1bac7%40isocpp.org.
------=_Part_458_1247808455.1476376108187
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, October 13, 2016 at 11:14:11 AM UTC-4, Barry =
Revzin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>SB does not f=
latten anything. It simply looks at public members of a type. [...]</div><d=
iv>And yet, C2 and C will not be different in terms of aggregate initializa=
tion. Your whole premise is that SB should work like the reverse of AI. <br=
></div></div></blockquote><div><br></div><div>Maybe I misworded the origina=
l proposal, but our premise isn't that SB and AI should be inverses. Th=
e premise is that an aggregate is just a collection of values - whether tho=
se values are all in one type directly or not.</div></div></blockquote><div=
><br>This premise is not supported by the C++ standard's definition for=
"aggregate". An aggregate is a collection of <i>objects</i>, not=
of values. And the subobjects in an aggregate may themselves have subobjec=
ts. "whether those values are all in one type directly or not" is=
not something the C++ standard dismisses. The arrangement of objects in an=
aggregate <i>matters</i>, not just in their order, but in which subobjects=
they are members of.<br><br>Aggregates are not flat in C++, and nothing in=
the standard has ever made them so.<br><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"ltr"><div>SB should be able to unpack an ag=
gregate into all of its underlying values - which would be all the public m=
embers, not the base class subobjects. So yes, I agree that C and C2 would =
both be aggregate-initializable with two ints, but C really has two int mem=
bers so it should unpack into two ints - whereas C2 has a B and an int and =
should unpack in those.<br></div></div></blockquote><div><br>And you're=
explaining exactly why SB doesn't do this.<br><br>You believe that a b=
ase class member should be treated as if it were a direct member of the der=
ived class. I believe otherwise. The standard's aggregate rules don'=
;t agree with you either. As such, one user will expect SB to unpack the &q=
uot;underlying values", while another user will expect SB to unpack th=
e <i>subobjects</i> in the type.<br><br>By forbidding this case entirely, t=
he standard ensures that there is no confusion.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cda97908-314b-4ff6-aba7-c67f92b1bac7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cda97908-314b-4ff6-aba7-c67f92b1bac7=
%40isocpp.org</a>.<br />
------=_Part_458_1247808455.1476376108187--
------=_Part_457_702746525.1476376108187--
.
Author: Victor Dyachenko <victor.dyachenko@gmail.com>
Date: Thu, 13 Oct 2016 10:50:37 -0700 (PDT)
Raw View
------=_Part_529_1044622004.1476381037453
Content-Type: multipart/alternative;
boundary="----=_Part_530_1074440246.1476381037454"
------=_Part_530_1074440246.1476381037454
Content-Type: text/plain; charset=UTF-8
On Thursday, October 13, 2016 at 5:18:41 PM UTC+3, Barry Revzin wrote:
>
>
>
> On Thursday, October 13, 2016 at 8:59:47 AM UTC-5, Nicol Bolas wrote:
>>
>>
>> struct B { int x; };
>> struct C : B { int y; };
>>
>> C c{1, 2}; // ok in C++17
>>
>> That does work, but it only works because of the use of brace elision.
>> The initializer ought to be `C c{{1}, 2};`, but C++ allows us to elide the
>> brace for an aggregate.
>>
>
> Right, because C conceptually is just a thing that has two named ints.
>
Second this.
struct B { int base_part; } ;
struct D1 : B
{
int d1_part;
};
struct D2 : B
{
int d2_part
};
Is the same as
struct D1
{
int base_part;
int d1_part;
};
struct D2
{
int base_part;
int d2_part
};
In both cases usage of the struct looks like:
D1 d1;
d1.base_part;
d1.d1_part;
so structured binding must work for both cases as
auto [base_part, d1_part] = D1{...};
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/49abbab8-b8c2-449d-9102-83fbf0afd347%40isocpp.org.
------=_Part_530_1074440246.1476381037454
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, October 13, 2016 at 5:18:41 PM UTC+3, Barry R=
evzin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
br><br>On Thursday, October 13, 2016 at 8:59:47 AM UTC-5, Nicol Bolas wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px"><code><div><span style=3D"color:#008">struct</sp=
an><span style=3D"color:#000"> B </span><span style=3D"color:#660">{</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">int</span><sp=
an style=3D"color:#000"> x</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">};</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">struct</span><span st=
yle=3D"color:#000"> C </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> B </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"> </span><span style=3D"color:#008">int</span><span style=3D"co=
lor:#000"> y</span><span style=3D"color:#660">;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000=
"><br><br>C c</span><span style=3D"color:#660">{</span><span style=3D"color=
:#066">1</span><span style=3D"color:#660">,</span><span style=3D"color:#000=
"> </span><span style=3D"color:#066">2</span><span style=3D"color:#660">};<=
/span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0</span><span style=3D=
"color:#800">// ok in C++17</span></div></code></div><br>That does work, bu=
t it only works because of the use of brace elision. The initializer ought =
to be `C c{{1}, 2};`, but C++ allows us to elide the brace for an aggregate=
..<br></div></blockquote><div><br></div><div>Right, because C conceptually i=
s just a thing that has two named ints.<br></div></div></blockquote><div>Se=
cond this.<br><br></div><div class=3D"prettyprint" style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> B </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> base_part</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> D1 =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> B<br></span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> d1_part</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> D2 </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> B<br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> d2_part<br></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code>=
</div><div><br>Is the same as<br><br><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> D1<br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> base_part</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> d1_part</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> D2<br></span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> base_part</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> d2_part<br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br><br></span></div></code></div><br>In both cases usag=
e of the struct looks like:<br><br><div class=3D"prettyprint" style=3D"back=
ground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-=
style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">D1 d1</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>d1</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">bas=
e_part</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>d1</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">d1_part</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></code></div><=
br>so structured binding must work for both cases as<br><br><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-=
word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">[</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">base_part</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> d1_part</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">]</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> D1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{...};</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code=
></div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/49abbab8-b8c2-449d-9102-83fbf0afd347%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/49abbab8-b8c2-449d-9102-83fbf0afd347=
%40isocpp.org</a>.<br />
------=_Part_530_1074440246.1476381037454--
------=_Part_529_1044622004.1476381037453--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 13 Oct 2016 23:38:52 +0200
Raw View
This is a multi-part message in MIME format.
--------------424447AB4A7BF63D387791E1
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 13/10/2016 =C3=A0 14:16, Barry Revzin a =C3=A9crit :
> We believe that there's a gap in coverage between what kinds of types=20
> you can decompose with structured bindings, now that we have extended=20
> the concept of aggregate. We also believe that the kind of scaffolding=20
> necessary to support structured bindings could be extended to be=20
> useful in other contexts - at the very least std::apply() but also any=20
> other metaprogramming. This proposal attempts to bridge all those gaps.
Hi,
it seems you missed P0327 (revision 0 available in Oulu. EGW forwarded=20
it to the LEWG. I have updated the version for Issaquah even if I have=20
not had the time to reword the wording which contains some of the needed=20
adaptation and extra algorithms on Product types (there are a lot of more).
Product-Type access -=20
https://github.com/viboes/std-make/blob/master/doc/proposal/reflection/p032=
7r1.md
My approach in P0327 is to change the wording of Struture binding so=20
that it is defined in terms of the size and elements of the type. Then=20
we define the function product_type::get and the trait=20
product_type::size in function of these common terms. The drawback of my=20
approach is that I change the name of the access and so we need to=20
redefine some functions. However I believe that it is better this way as=20
it is more explicit, avoid clashes, associate the functions and traits=20
to a concept.
I don't know why=20
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1691.html had=20
no follow up, but I believe that this paper identify a lot of issues=20
that have not been solved yet. I'm preparing a paper proposing an=20
alternative approach to customization points, but I had not enough time=20
got Issaquah. I believe that the customization points shouldn't pollute=20
the std space as we are doing up to now. We have begin/end for Range,=20
swap for Swappable, there is a proposal for hash_value for Hashable, and=20
others I don't remember.
If your proposal has more acceptation I'll be all for as soon as we have=20
a library access for all these kind of type, which I curiously named of=20
Product Types ;-)
Best,
Vicente
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/305a656d-327a-d03f-5458-9b21aaba9235%40wanadoo.f=
r.
--------------424447AB4A7BF63D387791E1
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dwindows-1252"
http-equiv=3D"Content-Type">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 13/10/2016 =C3=A0 14:16, Barry Revzin=
a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:dd89a60a-5bc2-4560-9343-212dcbf56cb1@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">We believe that there's a gap in coverage between
what kinds of types you can decompose with structured bindings,
now that we have extended the concept of aggregate. We also
believe that the kind of scaffolding necessary to support
structured bindings could be extended to be useful in other
contexts - at the very least std::apply() but also any other
metaprogramming. This proposal attempts to bridge all those
gaps.=C2=A0</div>
</blockquote>
<br>
Hi,<br>
<br>
it seems you missed P0327 (revision 0 available in Oulu. EGW=C2=A0
forwarded it to the LEWG. I have updated the version for Issaquah
even if I have not had the time to reword the wording which contains
some of the needed adaptation and extra algorithms on Product types
(there are a lot of more).<br>
<br>
=C2=A0=C2=A0 Product-Type access=C2=A0 -
<a class=3D"moz-txt-link-freetext"
href=3D"https://github.com/viboes/std-make/blob/master/doc/proposal/reflect=
ion/p0327r1.md">https://github.com/viboes/std-make/blob/master/doc/proposal=
/reflection/p0327r1.md</a><br>
<br>
My approach in P0327 is to change the wording of Struture binding so
that it is defined in terms of the size and elements of the type.
Then we define the function product_type::get and the trait
product_type::size in function of these common terms. The drawback
of my approach is that I change the name of the access and so we
need to redefine some functions. However I believe that it is better
this way as it is more explicit, avoid clashes, associate the
functions and traits to a concept.<br>
<br>
I don't know why =C2=A0 <a class=3D"moz-txt-link-freetext"
href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1691.html"=
>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1691.html
</a><span class=3D"moz-txt-link-freetext">had no follow up, but I
believe that this paper identify a lot of issues that have not
been solved yet. I'm preparing a paper proposing an alternative
approach to customization points, but I had not enough time got
Issaquah. I believe that the customization points shouldn't
pollute the </span>std space as we are doing up to now. We have
begin/end for Range, swap for Swappable, there is a proposal for
hash_value for Hashable, and others I don't remember.<br>
<br>
If your proposal has more acceptation I'll be all for as soon as we
have a library access for all these kind of type, which I curiously
named of Product Types ;-)<br>
<br>
Best,<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/305a656d-327a-d03f-5458-9b21aaba9235%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/305a656d-327a-d03f-5458-9b21aaba9235=
%40wanadoo.fr</a>.<br />
--------------424447AB4A7BF63D387791E1--
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Thu, 13 Oct 2016 16:43:30 -0700 (PDT)
Raw View
------=_Part_961_1217747617.1476402210471
Content-Type: multipart/alternative;
boundary="----=_Part_962_963787257.1476402210471"
------=_Part_962_963787257.1476402210471
Content-Type: text/plain; charset=UTF-8
>
>
> And you're explaining exactly why SB doesn't do this.
>
> You believe that a base class member should be treated as if it were a
> direct member of the derived class. I believe otherwise. The standard's
> aggregate rules don't agree with you either. As such, one user will expect
> SB to unpack the "underlying values", while another user will expect SB to
> unpack the *subobjects* in the type.
>
> By forbidding this case entirely, the standard ensures that there is no
> confusion.
>
But SB already does unpack the members, not the subobjects. Consider:
struct empty { };
struct A { int x; };
struct B : A { };
A makeA();
B makeB();
auto [v1] = makeA();
auto [v2] = makeB();
Based on the definitions in the standard, A has two elements (an empty and
an int) and B has one element (an A), but when we use structured bindings,
in both cases we only need one single name in the identifier list and both
v1 and v2 are ints.
We've already taken the step of enumerating members non-static data members
in declaration order for structured bindings. All I want to do is apply
that same logic to more kinds of types and have that enumeration available
in a metaprogramming context.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/efa54c85-4007-4f25-a331-ab54a16ab6f3%40isocpp.org.
------=_Part_962_963787257.1476402210471
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><br>And you're explaining exactly why SB doesn't do this.<=
br><br>You believe that a base class member should be treated as if it were=
a direct member of the derived class. I believe otherwise. The standard=
9;s aggregate rules don't agree with you either. As such, one user will=
expect SB to unpack the "underlying values", while another user =
will expect SB to unpack the <i>subobjects</i> in the type.<br><br>By forbi=
dding this case entirely, the standard ensures that there is no confusion.<=
/div></div></blockquote><div><br></div><div>But SB already does unpack the =
members, not the subobjects. Consider:</div><div><br></div><div><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> empty </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> A </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> B </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> A </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br>A makeA</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br>B makeB</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">[</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">v1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">]<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> makeA</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">[</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">v</span><font color=3D"#666600"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">2</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">]</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> makeB</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span></fo=
nt></div></code></div><div><br></div></div><div>Based on the definitions in=
the standard, A has two elements (an empty and an int) and B has one eleme=
nt (an A), but when we use structured bindings, in both cases we only need =
one single name in the identifier list and both v1 and v2 are ints.=C2=A0</=
div><div><br>We've already taken the step of enumerating members non-st=
atic data members in declaration order for structured bindings. All I want =
to do is apply that same logic to more kinds of types and have that enumera=
tion available in a metaprogramming context.=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/efa54c85-4007-4f25-a331-ab54a16ab6f3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/efa54c85-4007-4f25-a331-ab54a16ab6f3=
%40isocpp.org</a>.<br />
------=_Part_962_963787257.1476402210471--
------=_Part_961_1217747617.1476402210471--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 14 Oct 2016 08:57:42 +0200
Raw View
This is a multi-part message in MIME format.
--------------EF0EE0983CFA271E9ECB133F
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 14/10/2016 =C3=A0 01:43, Barry Revzin a =C3=A9crit :
>
>
> And you're explaining exactly why SB doesn't do this.
>
> You believe that a base class member should be treated as if it
> were a direct member of the derived class. I believe otherwise.
> The standard's aggregate rules don't agree with you either. As
> such, one user will expect SB to unpack the "underlying values",
> while another user will expect SB to unpack the /subobjects/ in
> the type.
>
> By forbidding this case entirely, the standard ensures that there
> is no confusion.
>
>
> But SB already does unpack the members, not the subobjects. Consider:
>
> |
> structempty {};
> structA {intx;};
> structB :A {};
>
> A makeA();
> B makeB();
>
> auto[v1]=3DmakeA();
> auto[v2]=3DmakeB();
> |
>
> Based on the definitions in the standard, A has two elements (an empty=20
> and an int) and B has one element (an A), but when we use structured=20
> bindings, in both cases we only need one single name in the identifier=20
> list and both v1 and v2 are ints.
>
Good point. C++17 is not finished yet, and if we consider that this is=20
not what we wanted, we should fix it now. IMHO we wanted to delay the=20
decision otherwise it would had been proposed.
For what I know, this was not the intention. May be I'm wrong.
> We've already taken the step of enumerating members non-static data=20
> members in declaration order for structured bindings.
As I see it: empty base classes and derived classes without NSDM don't=20
play in structure binding C++17.
This is almost in line with aggregate initialization
See http://melpon.org/wandbox/permlink/xakhsxNTIRcjiWJg
Note that aggregate initialization doesn't allows neither to initialize=20
an empty base class using {}. and that it allows to initialize
D d1 =3D {1, 2};
D d2 =3D {{1, 2}};
D d3 =3D {c1};
D d4 =3D {{{1}, 2}};
D d5 =3D {{a1, 2}};
The question is what we would like for structured binding if applied=20
when more than one class of the hierarchy has NSDM public members
What do we want
a) auto [b, j] =3D makeC(); // b is B i is int
or
b) auto [i, j] =3D makeC(); // i and j are int
If a) we would need to support
auto [[i], j] =3D makeC(); // i and j are int
?
> All I want to do is apply that same logic to more kinds of types and=20
> have that enumeration available in a metaprogramming context.
I agree. I would like also we apply the same logic for aggregate=20
initialization, structure binding if it was yet possible.
I believe that flat aggregate initialization was syntactic sugar error.=20
Too late to change this.
Now we have the option to choose flat or nested structure binding in C++20.
If C++17 wording doesn't implies flat structure binding we will see what=20
we do for calss C for C++20.
If C++17 wording implies flat structure binding we should decide if we=20
want it and if so we should have also flat structure binding for=20
classes C and D.
Vicente
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/4ecaea2b-35d0-4c1b-706c-9f1d668b112d%40wanadoo.f=
r.
--------------EF0EE0983CFA271E9ECB133F
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 14/10/2016 =C3=A0 01:43, Barry Revzin=
a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:efa54c85-4007-4f25-a331-ab54a16ab6f3@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div dir=3D"ltr">
<div><br>
And you're explaining exactly why SB doesn't do this.<br>
<br>
You believe that a base class member should be treated as
if it were a direct member of the derived class. I believe
otherwise. The standard's aggregate rules don't agree with
you either. As such, one user will expect SB to unpack the
"underlying values", while another user will expect SB to
unpack the <i>subobjects</i> in the type.<br>
<br>
By forbidding this case entirely, the standard ensures
that there is no confusion.</div>
</div>
</blockquote>
<div><br>
</div>
<div>But SB already does unpack the members, not the subobjects.
Consider:</div>
<div><br>
</div>
<div>
<div class=3D"prettyprint" style=3D"background-color: rgb(250,
250, 250); border-color: rgb(187, 187, 187); border-style:
solid; border-width: 1px; word-wrap: break-word;"><code
class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #008;"
class=3D"styled-by-prettify">struct</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> empt=
y
</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">{</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify"> </span><span
style=3D"color: #660;" class=3D"styled-by-prettify">};</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #008;"
class=3D"styled-by-prettify">struct</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> A </=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> x</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">};</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #008;"
class=3D"styled-by-prettify">struct</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> B </=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> A </=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">};</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
<br>
A makeA</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">();</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
B makeB</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">();</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
<br>
</span><span style=3D"color: #008;"
class=3D"styled-by-prettify">auto</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">[</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">v1</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">]</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> make=
A</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">();</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span><span style=3D"color: #008;"
class=3D"styled-by-prettify">auto</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">[</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify">v</sp=
an><font
color=3D"#666600"><span style=3D"color: #000;"
class=3D"styled-by-prettify">2</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">]</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span
style=3D"color: #000;" class=3D"styled-by-prettify">
makeB</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">();</span></font></div>
</code></div>
<div><br>
</div>
</div>
<div>Based on the definitions in the standard, A has two
elements (an empty and an int) and B has one element (an A),
but when we use structured bindings, in both cases we only
need one single name in the identifier list and both v1 and v2
are ints.=C2=A0</div>
<div><br>
</div>
</div>
</blockquote>
Good point. C++17 is not finished yet, and if we consider that this
is not what we wanted, we should fix it now. IMHO we wanted to delay
the decision otherwise it would had been proposed.<br>
For what I know, this was not the intention. May be I'm wrong.<br>
<br>
<blockquote
cite=3D"mid:efa54c85-4007-4f25-a331-ab54a16ab6f3@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>We've already taken the step of enumerating members
non-static data members in declaration order for structured
bindings. </div>
</div>
</blockquote>
As I see it: empty base classes and derived classes without NSDM
don't play in structure binding C++17. <br>
This is almost in line with aggregate initialization<br>
<br>
See <a class=3D"moz-txt-link-freetext" href=3D"http://melpon.org/wandbo=
x/permlink/xakhsxNTIRcjiWJg">http://melpon.org/wandbox/permlink/xakhsxNTIRc=
jiWJg</a><br>
<br>
Note that aggregate initialization doesn't allows neither to
initialize an empty base class using {}. and that it allows to
initialize<br>
<br>
=C2=A0=C2=A0=C2=A0 D d1 =3D {1, 2};<br>
=C2=A0=C2=A0=C2=A0 D d2 =3D {{1, 2}};<br>
=C2=A0=C2=A0=C2=A0 D d3 =3D {c1};<br>
=C2=A0=C2=A0=C2=A0 D d4 =3D {{{1}, 2}};<br>
=C2=A0=C2=A0=C2=A0 D d5 =3D {{a1, 2}};<br>
<br>
The question is what we would like for=C2=A0 structured binding if
applied when more than one class of the hierarchy has NSDM public
members<br>
<br>
What do we=C2=A0 want <br>
a) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [b, j] =3D makeC(); // b i=
s B=C2=A0 i is int<br>
or<br>
b) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [i, j] =3D makeC(); // i a=
nd j are int <br>
<br>
If a) we would need to support<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [[i], j] =3D makeC(); /=
/ i and j are int<br>
?<br>
<br>
<blockquote
cite=3D"mid:efa54c85-4007-4f25-a331-ab54a16ab6f3@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>All I want to do is apply that same logic to more kinds of
types and have that enumeration available in a metaprogramming
context.=C2=A0</div>
</div>
</blockquote>
I agree. I would like also we apply the same logic for aggregate
initialization, structure binding if it was yet possible.<br>
I believe that flat aggregate initialization was syntactic sugar
error. Too late to change this.<br>
Now we have the option to choose flat or nested structure binding in
C++20. <br>
<br>
If C++17 wording doesn't implies flat structure binding we will see
what we do for calss C for C++20.<br>
If C++17 wording implies flat structure binding we should decide if
we want it and if so we should=C2=A0 have also flat structure binding f=
or
classes C and D.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/4ecaea2b-35d0-4c1b-706c-9f1d668b112d%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4ecaea2b-35d0-4c1b-706c-9f1d668b112d=
%40wanadoo.fr</a>.<br />
--------------EF0EE0983CFA271E9ECB133F--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 14 Oct 2016 07:34:13 -0700 (PDT)
Raw View
------=_Part_925_22673788.1476455653742
Content-Type: multipart/alternative;
boundary="----=_Part_926_1081517020.1476455653743"
------=_Part_926_1081517020.1476455653743
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, October 14, 2016 at 2:57:45 AM UTC-4, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 14/10/2016 =C3=A0 01:43, Barry Revzin a =C3=A9crit :
>
>
>> And you're explaining exactly why SB doesn't do this.
>>
>> You believe that a base class member should be treated as if it were a=
=20
>> direct member of the derived class. I believe otherwise. The standard's=
=20
>> aggregate rules don't agree with you either. As such, one user will expe=
ct=20
>> SB to unpack the "underlying values", while another user will expect SB =
to=20
>> unpack the *subobjects* in the type.
>>
>> By forbidding this case entirely, the standard ensures that there is no=
=20
>> confusion.
>>
>
> But SB already does unpack the members, not the subobjects. Consider:
>
> struct empty { };
> struct A { int x; };
> struct B : A { };
>
> A makeA();
> B makeB();
>
> auto [v1] =3D makeA();
> auto [v2] =3D makeB();
>
> Based on the definitions in the standard, A has two elements (an empty an=
d=20
> an int) and B has one element (an A), but when we use structured bindings=
,=20
> in both cases we only need one single name in the identifier list and bot=
h=20
> v1 and v2 are ints.=20
>
> Good point. C++17 is not finished yet, and if we consider that this is no=
t=20
> what we wanted, we should fix it now. IMHO we wanted to delay the decisio=
n=20
> otherwise it would had been proposed.
> For what I know, this was not the intention. May be I'm wrong.
>
> We've already taken the step of enumerating members non-static data=20
> members in declaration order for structured bindings.=20
>
> As I see it: empty base classes and derived classes without NSDM don't=20
> play in structure binding C++17.=20
> This is almost in line with aggregate initialization
>
No, it is not.
If you change your `A` class to have two members, you cannot initialize `C`=
=20
3 members with 3 values in sequence. Well, not in accord with the=20
specification; Clang 4.0 head seems to not agree with that=20
<http://melpon.org/wandbox/permlink/tNXLtIfYzqslXgfS>. But the=20
specification itself is quite clear on this ([dcl.init.agg]/14):
> Otherwise, if the element is itself a subaggregate, brace elision is=20
assumed and the assignment-expression is considered for the initialization=
=20
of the *first element of the subaggregate*.=20
The only reason why your examples work as is is due to brace elision. Brace=
=20
elision allows `B` to initialize its inherited members via 2 elements, but=
=20
only by eliding the brace around B itself. That doesn't work for C because=
=20
it has direct members of its own. So the first element of the=20
braced-init-list will always initialize the entire base class `B` (which=20
initializes the first member of `A` via brace elision); the second element=
=20
will initialize the first direct member of `C`.
Again, Clang seems to be faulty here.
The question is what we would like for structured binding if applied when=
=20
> more than one class of the hierarchy has NSDM public members
>
> What do we want=20
> a) auto [b, j] =3D makeC(); // b is B i is int
> or
> b) auto [i, j] =3D makeC(); // i and j are int=20
>
> If a) we would need to support
> auto [[i], j] =3D makeC(); // i and j are int
> ?
>
The fact that this is a question is precisely why it is forbidden. We have=
=20
no easily-agreed-upon way to decide which to have, so for the time being,=
=20
we have neither.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/bc89c95c-b944-4115-b019-b5ae6970b0d7%40isocpp.or=
g.
------=_Part_926_1081517020.1476455653743
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, October 14, 2016 at 2:57:45 AM UTC-4, Vicente J=
.. Botet Escriba wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 14/10/2016 =C3=A0 01:43, Barry Revzin a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">
<div><br>
And you're explaining exactly why SB doesn't do this.=
<br>
<br>
You believe that a base class member should be treated as
if it were a direct member of the derived class. I believe
otherwise. The standard's aggregate rules don't agree=
with
you either. As such, one user will expect SB to unpack the
"underlying values", while another user will expect=
SB to
unpack the <i>subobjects</i> in the type.<br>
<br>
By forbidding this case entirely, the standard ensures
that there is no confusion.</div>
</div>
</blockquote>
<div><br>
</div>
<div>But SB already does unpack the members, not the subobjects.
Consider:</div>
<div><br>
</div>
<div>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><cod=
e>
<div><span style=3D"color:#008">struct</span><span style=3D"c=
olor:#000"> empty
</span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:=
#000"><br>
</span><span style=3D"color:#008">struct</span><span style=
=3D"color:#000"> A </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"> </span><span style=3D"color:#008">int</span><span style=3D"co=
lor:#000"> x</span><span style=3D"color:#660">;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000=
"><br>
</span><span style=3D"color:#008">struct</span><span style=
=3D"color:#000"> B </span><span style=3D"color:#660">:</span><span style=3D=
"color:#000"> A </span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:=
#000"><br>
<br>
A makeA</span><span style=3D"color:#660">();</span><span =
style=3D"color:#000"><br>
B makeB</span><span style=3D"color:#660">();</span><span =
style=3D"color:#000"><br>
<br>
</span><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">[</span><span style=3D"colo=
r:#000">v1</span><span style=3D"color:#660">]</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"=
> makeA</span><span style=3D"color:#660">();</span><span style=3D"color:#00=
0"><br>
</span><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">[</span><span style=3D"colo=
r:#000">v</span><font color=3D"#666600"><span style=3D"color:#000">2</span>=
<span style=3D"color:#660">]</span><span style=3D"color:#000"> </span><span=
style=3D"color:#660">=3D</span><span style=3D"color:#000">
makeB</span><span style=3D"color:#660">();</span></font=
></div>
</code></div>
<div><br>
</div>
</div>
<div>Based on the definitions in the standard, A has two
elements (an empty and an int) and B has one element (an A),
but when we use structured bindings, in both cases we only
need one single name in the identifier list and both v1 and v2
are ints.=C2=A0</div>
<div><br>
</div>
</div>
</blockquote>
Good point. C++17 is not finished yet, and if we consider that this
is not what we wanted, we should fix it now. IMHO we wanted to delay
the decision otherwise it would had been proposed.<br>
For what I know, this was not the intention. May be I'm wrong.<br>
<br>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div>We've already taken the step of enumerating members
non-static data members in declaration order for structured
bindings. </div>
</div>
</blockquote>
As I see it: empty base classes and derived classes without NSDM
don't play in structure binding C++17. <br>
This is almost in line with aggregate initialization<br></div></blockqu=
ote><div><br>No, it is not.<br><br>If you change your `A` class to have two=
members, you cannot initialize `C` 3 members with 3 values in sequence. We=
ll, not in accord with the specification; <a href=3D"http://melpon.org/wand=
box/permlink/tNXLtIfYzqslXgfS">Clang 4.0 head seems to not agree with that<=
/a>. But the specification itself is quite clear on this ([dcl.init.agg]/14=
):<br><br>>=C2=A0 Otherwise, if the element is itself a subaggregate, br=
ace elision is assumed and the assignment-expression is considered for the =
initialization of the <b>first element of the subaggregate</b>. <br><br>The=
only reason why your examples work as is is due to brace elision. Brace el=
ision allows `B` to initialize its inherited members via 2 elements, but on=
ly by eliding the brace around B itself. That doesn't work for C becaus=
e it has direct members of its own. So the first element of the braced-init=
-list will always initialize the entire base class `B` (which initializes t=
he first member of `A` via brace elision); the second element will initiali=
ze the first direct member of `C`.<br><br>Again, Clang seems to be faulty h=
ere.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=
=3D"#FFFFFF" text=3D"#000000">
=20
The question is what we would like for=C2=A0 structured binding if
applied when more than one class of the hierarchy has NSDM public
members<br>
<br>
What do we=C2=A0 want <br>
a) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [b, j] =3D makeC(); // b i=
s B=C2=A0 i is int<br>
or<br>
b) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [i, j] =3D makeC(); // i a=
nd j are int <br>
<br>
If a) we would need to support<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [[i], j] =3D makeC(); /=
/ i and j are int<br>
?<br></div></blockquote><div><br>The fact that this is a question is pr=
ecisely why it is forbidden. We have no easily-agreed-upon way to decide wh=
ich to have, so for the time being, we have neither.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bc89c95c-b944-4115-b019-b5ae6970b0d7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bc89c95c-b944-4115-b019-b5ae6970b0d7=
%40isocpp.org</a>.<br />
------=_Part_926_1081517020.1476455653743--
------=_Part_925_22673788.1476455653742--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Fri, 14 Oct 2016 11:11:21 -0700
Raw View
--001a11402d105b1e09053ed727f9
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Fri, Oct 14, 2016 at 7:34 AM, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Friday, October 14, 2016 at 2:57:45 AM UTC-4, Vicente J. Botet Escriba
> wrote:
>>
>> Le 14/10/2016 =C3=A0 01:43, Barry Revzin a =C3=A9crit :
>>
>>
>>> And you're explaining exactly why SB doesn't do this.
>>>
>>> You believe that a base class member should be treated as if it were a
>>> direct member of the derived class. I believe otherwise. The standard's
>>> aggregate rules don't agree with you either. As such, one user will exp=
ect
>>> SB to unpack the "underlying values", while another user will expect SB=
to
>>> unpack the *subobjects* in the type.
>>>
>>> By forbidding this case entirely, the standard ensures that there is no
>>> confusion.
>>>
>>
>> But SB already does unpack the members, not the subobjects. Consider:
>>
>> struct empty { };
>> struct A { int x; };
>> struct B : A { };
>>
>> A makeA();
>> B makeB();
>>
>> auto [v1] =3D makeA();
>> auto [v2] =3D makeB();
>>
>> Based on the definitions in the standard, A has two elements (an empty
>> and an int) and B has one element (an A), but when we use structured
>> bindings, in both cases we only need one single name in the identifier l=
ist
>> and both v1 and v2 are ints.
>>
>> Good point. C++17 is not finished yet, and if we consider that this is
>> not what we wanted, we should fix it now. IMHO we wanted to delay the
>> decision otherwise it would had been proposed.
>> For what I know, this was not the intention. May be I'm wrong.
>>
>> We've already taken the step of enumerating members non-static data
>> members in declaration order for structured bindings.
>>
>> As I see it: empty base classes and derived classes without NSDM don't
>> play in structure binding C++17.
>> This is almost in line with aggregate initialization
>>
>
> No, it is not.
>
> If you change your `A` class to have two members, you cannot initialize
> `C` 3 members with 3 values in sequence. Well, not in accord with the
> specification; Clang 4.0 head seems to not agree with that
> <http://melpon.org/wandbox/permlink/tNXLtIfYzqslXgfS>. But the
> specification itself is quite clear on this ([dcl.init.agg]/14):
>
> > Otherwise, if the element is itself a subaggregate, brace elision is
> assumed and the assignment-expression is considered for the initializatio=
n
> of the *first element of the subaggregate*.
>
You don't *stop* after the first element of the subaggregate, though.
/13: "enough initializer-clauses from the list are taken to initialize the
elements of the subaggregate; any remaining initializer-clauses are left to
initialize the next element of the aggregate of which the current
subaggregate is an element"
The only reason why your examples work as is is due to brace elision. Brace
> elision allows `B` to initialize its inherited members via 2 elements, bu=
t
> only by eliding the brace around B itself. That doesn't work for C becaus=
e
> it has direct members of its own. So the first element of the
> braced-init-list will always initialize the entire base class `B` (which
> initializes the first member of `A` via brace elision); the second elemen=
t
> will initialize the first direct member of `C`.
>
> Again, Clang seems to be faulty here.
>
No, Clang is behaving per the standard and per the intent. Aggregate
initialization of base classes works exactly as if the base class were an
(initial) non-static data member. You can elide braces as normal.
The question is what we would like for structured binding if applied when
>> more than one class of the hierarchy has NSDM public members
>>
>> What do we want
>> a) auto [b, j] =3D makeC(); // b is B i is int
>> or
>> b) auto [i, j] =3D makeC(); // i and j are int
>>
>> If a) we would need to support
>> auto [[i], j] =3D makeC(); // i and j are int
>> ?
>>
>
> The fact that this is a question is precisely why it is forbidden. We hav=
e
> no easily-agreed-upon way to decide which to have, so for the time being,
> we have neither.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/bc89c95c-b944-4115-
> b019-b5ae6970b0d7%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bc89c95c-b9=
44-4115-b019-b5ae6970b0d7%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAOfiQqkCCNZ%3DBnzLiSO_rARgez2wYuoHHh6fTSivAFnzT=
Wwymw%40mail.gmail.com.
--001a11402d105b1e09053ed727f9
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Oct 14, 2016 at 7:34 AM, Nicol Bolas <span dir=3D"ltr"><<a href=3D"m=
ailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><span class=3D"gmail-">On Friday, October 14, 2016 at 2:57:45 AM U=
TC-4, Vicente J. Botet Escriba wrote:<blockquote class=3D"gmail_quote" styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin=
g-left:1ex">
=20
=20
=20
<div bgcolor=3D"#FFFFFF">
<div>Le 14/10/2016 =C3=A0 01:43, Barry Revzin a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">
<div><br>
And you're explaining exactly why SB doesn't do this.=
<br>
<br>
You believe that a base class member should be treated as
if it were a direct member of the derived class. I believe
otherwise. The standard's aggregate rules don't agree=
with
you either. As such, one user will expect SB to unpack the
"underlying values", while another user will expect=
SB to
unpack the <i>subobjects</i> in the type.<br>
<br>
By forbidding this case entirely, the standard ensures
that there is no confusion.</div>
</div>
</blockquote>
<div><br>
</div>
<div>But SB already does unpack the members, not the subobjects.
Consider:</div>
<div><br>
</div>
<div>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><cod=
e>
<div><span style=3D"color:rgb(0,0,136)">struct</span><span st=
yle=3D"color:rgb(0,0,0)"> empty
</span><span style=3D"color:rgb(102,102,0)">{</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">};</=
span><span style=3D"color:rgb(0,0,0)"><br>
</span><span style=3D"color:rgb(0,0,136)">struct</span><spa=
n style=3D"color:rgb(0,0,0)"> A </span><span style=3D"color:rgb(102,102,0)"=
>{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> x</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,=
0)"><br>
</span><span style=3D"color:rgb(0,0,136)">struct</span><spa=
n style=3D"color:rgb(0,0,0)"> B </span><span style=3D"color:rgb(102,102,0)"=
>:</span><span style=3D"color:rgb(0,0,0)"> A </span><span style=3D"color:rg=
b(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><br>
<br>
A makeA</span><span style=3D"color:rgb(102,102,0)">();</s=
pan><span style=3D"color:rgb(0,0,0)"><br>
B makeB</span><span style=3D"color:rgb(102,102,0)">();</s=
pan><span style=3D"color:rgb(0,0,0)"><br>
<br>
</span><span style=3D"color:rgb(0,0,136)">auto</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">[</=
span><span style=3D"color:rgb(0,0,0)">v1</span><span style=3D"color:rgb(102=
,102,0)">]</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> makeA</span=
><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:rgb(0,=
0,0)"><br>
</span><span style=3D"color:rgb(0,0,136)">auto</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">[</=
span><span style=3D"color:rgb(0,0,0)">v</span><font color=3D"#666600"><span=
style=3D"color:rgb(0,0,0)">2</span><span style=3D"color:rgb(102,102,0)">]<=
/span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102=
,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)">
makeB</span><span style=3D"color:rgb(102,102,0)">();</s=
pan></font></div>
</code></div>
<div><br>
</div>
</div>
<div>Based on the definitions in the standard, A has two
elements (an empty and an int) and B has one element (an A),
but when we use structured bindings, in both cases we only
need one single name in the identifier list and both v1 and v2
are ints.=C2=A0</div>
<div><br>
</div>
</div>
</blockquote>
Good point. C++17 is not finished yet, and if we consider that this
is not what we wanted, we should fix it now. IMHO we wanted to delay
the decision otherwise it would had been proposed.<br>
For what I know, this was not the intention. May be I'm wrong.<br>
<br>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div>We've already taken the step of enumerating members
non-static data members in declaration order for structured
bindings. </div>
</div>
</blockquote>
As I see it: empty base classes and derived classes without NSDM
don't play in structure binding C++17. <br>
This is almost in line with aggregate initialization<br></div></blockqu=
ote></span><div><br>No, it is not.<br><br>If you change your `A` class to h=
ave two members, you cannot initialize `C` 3 members with 3 values in seque=
nce. Well, not in accord with the specification; <a href=3D"http://melpon.o=
rg/wandbox/permlink/tNXLtIfYzqslXgfS" target=3D"_blank">Clang 4.0 head seem=
s to not agree with that</a>. But the specification itself is quite clear o=
n this ([dcl.init.agg]/14):<br><br>>=C2=A0 Otherwise, if the element is =
itself a subaggregate, brace elision is assumed and the assignment-expressi=
on is considered for the initialization of the <b>first element of the suba=
ggregate</b>. <br></div></div></blockquote><div><br></div><div>You don'=
t *stop* after the first element of the subaggregate, though.</div><div><br=
></div><div>/13: "enough initializer-clauses from the list are taken t=
o initialize the elements of the subaggregate; any remaining initializer-cl=
auses are left to initialize the next element of the aggregate of which the=
current subaggregate is an element"</div><div><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>The only reason =
why your examples work as is is due to brace elision. Brace elision allows =
`B` to initialize its inherited members via 2 elements, but only by eliding=
the brace around B itself. That doesn't work for C because it has dire=
ct members of its own. So the first element of the braced-init-list will al=
ways initialize the entire base class `B` (which initializes the first memb=
er of `A` via brace elision); the second element will initialize the first =
direct member of `C`.<br><br>Again, Clang seems to be faulty here.<br></div=
></div></blockquote><div><br></div><div>No, Clang is behaving per the stand=
ard and per the intent. Aggregate initialization of base classes works exac=
tly as if the base class were an (initial) non-static data member. You can =
elide braces as normal.</div><div><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr"><div></div><span class=3D"gmail-"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor=3D"#FFFFFF">
=20
The question is what we would like for=C2=A0 structured binding if
applied when more than one class of the hierarchy has NSDM public
members<br>
<br>
What do we=C2=A0 want <br>
a) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [b, j] =3D makeC(); // b i=
s B=C2=A0 i is int<br>
or<br>
b) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [i, j] =3D makeC(); // i a=
nd j are int <br>
<br>
If a) we would need to support<br>
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto [[i], j] =3D makeC(); /=
/ i and j are int<br>
?<br></div></blockquote></span><div><br>The fact that this is a questio=
n is precisely why it is forbidden. We have no easily-agreed-upon way to de=
cide which to have, so for the time being, we have neither.<br></div></div>=
<span class=3D"gmail-">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bc89c95c-b944-4115-b019-b5ae6970b0d7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/bc89=
c95c-b944-4115-<wbr>b019-b5ae6970b0d7%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkCCNZ%3DBnzLiSO_rARgez2wYuoHHh=
6fTSivAFnzTWwymw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkCCNZ%3D=
BnzLiSO_rARgez2wYuoHHh6fTSivAFnzTWwymw%40mail.gmail.com</a>.<br />
--001a11402d105b1e09053ed727f9--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 14 Oct 2016 12:53:20 -0700 (PDT)
Raw View
------=_Part_1102_1024783470.1476474800309
Content-Type: multipart/alternative;
boundary="----=_Part_1103_512371905.1476474800309"
------=_Part_1103_512371905.1476474800309
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, October 14, 2016 at 2:11:28 PM UTC-4, Richard Smith wrote:
>
> On Fri, Oct 14, 2016 at 7:34 AM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>> On Friday, October 14, 2016 at 2:57:45 AM UTC-4, Vicente J. Botet Escrib=
a=20
>> wrote:
>>>
>>> Le 14/10/2016 =C3=A0 01:43, Barry Revzin a =C3=A9crit :
>>>
>>>
>>>> And you're explaining exactly why SB doesn't do this.
>>>>
>>>> You believe that a base class member should be treated as if it were a=
=20
>>>> direct member of the derived class. I believe otherwise. The standard'=
s=20
>>>> aggregate rules don't agree with you either. As such, one user will ex=
pect=20
>>>> SB to unpack the "underlying values", while another user will expect S=
B to=20
>>>> unpack the *subobjects* in the type.
>>>>
>>>> By forbidding this case entirely, the standard ensures that there is n=
o=20
>>>> confusion.
>>>>
>>>
>>> But SB already does unpack the members, not the subobjects. Consider:
>>>
>>> struct empty { };
>>> struct A { int x; };
>>> struct B : A { };
>>>
>>> A makeA();
>>> B makeB();
>>>
>>> auto [v1] =3D makeA();
>>> auto [v2] =3D makeB();
>>>
>>> Based on the definitions in the standard, A has two elements (an empty=
=20
>>> and an int) and B has one element (an A), but when we use structured=20
>>> bindings, in both cases we only need one single name in the identifier =
list=20
>>> and both v1 and v2 are ints.=20
>>>
>>> Good point. C++17 is not finished yet, and if we consider that this is=
=20
>>> not what we wanted, we should fix it now. IMHO we wanted to delay the=
=20
>>> decision otherwise it would had been proposed.
>>> For what I know, this was not the intention. May be I'm wrong.
>>>
>>> We've already taken the step of enumerating members non-static data=20
>>> members in declaration order for structured bindings.=20
>>>
>>> As I see it: empty base classes and derived classes without NSDM don't=
=20
>>> play in structure binding C++17.=20
>>> This is almost in line with aggregate initialization
>>>
>>
>> No, it is not.
>>
>> If you change your `A` class to have two members, you cannot initialize=
=20
>> `C` 3 members with 3 values in sequence. Well, not in accord with the=20
>> specification; Clang 4.0 head seems to not agree with that=20
>> <http://melpon.org/wandbox/permlink/tNXLtIfYzqslXgfS>. But the=20
>> specification itself is quite clear on this ([dcl.init.agg]/14):
>>
>> > Otherwise, if the element is itself a subaggregate, brace elision is=
=20
>> assumed and the assignment-expression is considered for the initializati=
on=20
>> of the *first element of the subaggregate*.=20
>>
>
> You don't *stop* after the first element of the subaggregate, though.
>
> /13: "enough initializer-clauses from the list are taken to initialize th=
e=20
> elements of the subaggregate; any remaining initializer-clauses are left =
to=20
> initialize the next element of the aggregate of which the current=20
> subaggregate is an element"
>
.... I did not know this.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/eceb809e-e3a5-4aa8-b161-3317c5b85d92%40isocpp.or=
g.
------=_Part_1103_512371905.1476474800309
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, October 14, 2016 at 2:11:28 PM UTC-4, Richard S=
mith wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><div class=3D"gmail_quote">On Fri, Oct 14, 2016 at 7:34 AM, Nicol Bolas =
<span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfusca=
ted-mailto=3D"aKmjVbQMAgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D=
9;javascript:';return true;" onclick=3D"this.href=3D'javascript:=
9;;return true;">jmck...@gmail.com</a>></span> wrote:<br><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><span>On Friday, Octobe=
r 14, 2016 at 2:57:45 AM UTC-4, Vicente J. Botet Escriba wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex">
=20
=20
=20
<div bgcolor=3D"#FFFFFF">
<div>Le 14/10/2016 =C3=A0 01:43, Barry Revzin a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">
<div><br>
And you're explaining exactly why SB doesn't do this.=
<br>
<br>
You believe that a base class member should be treated as
if it were a direct member of the derived class. I believe
otherwise. The standard's aggregate rules don't agree=
with
you either. As such, one user will expect SB to unpack the
"underlying values", while another user will expect=
SB to
unpack the <i>subobjects</i> in the type.<br>
<br>
By forbidding this case entirely, the standard ensures
that there is no confusion.</div>
</div>
</blockquote>
<div><br>
</div>
<div>But SB already does unpack the members, not the subobjects.
Consider:</div>
<div><br>
</div>
<div>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><cod=
e>
<div><span style=3D"color:rgb(0,0,136)">struct</span><span st=
yle=3D"color:rgb(0,0,0)"> empty
</span><span style=3D"color:rgb(102,102,0)">{</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">};</=
span><span style=3D"color:rgb(0,0,0)"><br>
</span><span style=3D"color:rgb(0,0,136)">struct</span><spa=
n style=3D"color:rgb(0,0,0)"> A </span><span style=3D"color:rgb(102,102,0)"=
>{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> x</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,=
0)"><br>
</span><span style=3D"color:rgb(0,0,136)">struct</span><spa=
n style=3D"color:rgb(0,0,0)"> B </span><span style=3D"color:rgb(102,102,0)"=
>:</span><span style=3D"color:rgb(0,0,0)"> A </span><span style=3D"color:rg=
b(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><br>
<br>
A makeA</span><span style=3D"color:rgb(102,102,0)">();</s=
pan><span style=3D"color:rgb(0,0,0)"><br>
B makeB</span><span style=3D"color:rgb(102,102,0)">();</s=
pan><span style=3D"color:rgb(0,0,0)"><br>
<br>
</span><span style=3D"color:rgb(0,0,136)">auto</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">[</=
span><span style=3D"color:rgb(0,0,0)">v1</span><span style=3D"color:rgb(102=
,102,0)">]</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"co=
lor:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> makeA</span=
><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:rgb(0,=
0,0)"><br>
</span><span style=3D"color:rgb(0,0,136)">auto</span><span =
style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">[</=
span><span style=3D"color:rgb(0,0,0)">v</span><font color=3D"#666600"><span=
style=3D"color:rgb(0,0,0)">2</span><span style=3D"color:rgb(102,102,0)">]<=
/span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102=
,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)">
makeB</span><span style=3D"color:rgb(102,102,0)">();</s=
pan></font></div>
</code></div>
<div><br>
</div>
</div>
<div>Based on the definitions in the standard, A has two
elements (an empty and an int) and B has one element (an A),
but when we use structured bindings, in both cases we only
need one single name in the identifier list and both v1 and v2
are ints.=C2=A0</div>
<div><br>
</div>
</div>
</blockquote>
Good point. C++17 is not finished yet, and if we consider that this
is not what we wanted, we should fix it now. IMHO we wanted to delay
the decision otherwise it would had been proposed.<br>
For what I know, this was not the intention. May be I'm wrong.<br>
<br>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div>We've already taken the step of enumerating members
non-static data members in declaration order for structured
bindings. </div>
</div>
</blockquote>
As I see it: empty base classes and derived classes without NSDM
don't play in structure binding C++17. <br>
This is almost in line with aggregate initialization<br></div></blockqu=
ote></span><div><br>No, it is not.<br><br>If you change your `A` class to h=
ave two members, you cannot initialize `C` 3 members with 3 values in seque=
nce. Well, not in accord with the specification; <a href=3D"http://melpon.o=
rg/wandbox/permlink/tNXLtIfYzqslXgfS" target=3D"_blank" rel=3D"nofollow" on=
mousedown=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fm=
elpon.org%2Fwandbox%2Fpermlink%2FtNXLtIfYzqslXgfS\x26sa\x3dD\x26sntz\x3d1\x=
26usg\x3dAFQjCNGs1NeI8uVcTHEyM1XmfEcZkia7aA';return true;" onclick=3D"t=
his.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fmelpon.org%2Fwa=
ndbox%2Fpermlink%2FtNXLtIfYzqslXgfS\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjC=
NGs1NeI8uVcTHEyM1XmfEcZkia7aA';return true;">Clang 4.0 head seems to no=
t agree with that</a>. But the specification itself is quite clear on this =
([dcl.init.agg]/14):<br><br>>=C2=A0 Otherwise, if the element is itself =
a subaggregate, brace elision is assumed and the assignment-expression is c=
onsidered for the initialization of the <b>first element of the subaggregat=
e</b>. <br></div></div></blockquote><div><br></div><div>You don't *stop=
* after the first element of the subaggregate, though.</div><div><br></div>=
<div>/13: "enough initializer-clauses from the list are taken to initi=
alize the elements of the subaggregate; any remaining initializer-clauses a=
re left to initialize the next element of the aggregate of which the curren=
t subaggregate is an element"</div></div></div></div></blockquote><div=
><br>... I did not know this.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/eceb809e-e3a5-4aa8-b161-3317c5b85d92%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/eceb809e-e3a5-4aa8-b161-3317c5b85d92=
%40isocpp.org</a>.<br />
------=_Part_1103_512371905.1476474800309--
------=_Part_1102_1024783470.1476474800309--
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Sun, 16 Oct 2016 12:31:47 -0700 (PDT)
Raw View
------=_Part_977_880798798.1476646307834
Content-Type: multipart/alternative;
boundary="----=_Part_978_1685763174.1476646307835"
------=_Part_978_1685763174.1476646307835
Content-Type: text/plain; charset=UTF-8
Here's a better draft where we're clarifying the problem set and dividing
the world of types into three cases. The paper isn't about aggregate
initialization - it's about wanting the machinery implicit to structured
bindings available in a metaprogramming context and wanting that machinery
to by default apply to more kinds of types.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/04845d0e-c10a-4b34-8c7f-ea6b2d32a33a%40isocpp.org.
------=_Part_978_1685763174.1476646307835
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Here's a better draft where we're clarifying the p=
roblem set and dividing the world of types into three cases. The paper isn&=
#39;t about aggregate initialization - it's about wanting the machinery=
implicit to structured bindings available in a metaprogramming context and=
wanting that machinery to by default apply to more kinds of types.=C2=A0</=
div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/04845d0e-c10a-4b34-8c7f-ea6b2d32a33a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/04845d0e-c10a-4b34-8c7f-ea6b2d32a33a=
%40isocpp.org</a>.<br />
------=_Part_978_1685763174.1476646307835--
------=_Part_977_880798798.1476646307834
Content-Type: text/html; charset=US-ASCII; name=tuple_like.html
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=tuple_like.html
X-Attachment-Id: a6c8f1c6-894f-4cb7-aebc-0cfa41bc5f75
Content-ID: <a6c8f1c6-894f-4cb7-aebc-0cfa41bc5f75>
<html>
<head>
<title>tuple-like</title>
<style>
p {text-align:justify}
li {text-align:justify}
blockquote.note
{
background-color:#E0E0E0;
padding-left: 15px;
padding-right: 15px;
padding-top: 1px;
padding-bottom: 1px;
}
ins {color:#00A000}
del {color:#A00000}
code {white-space:pre;}
</style>
</head>
<body>
<address align=right>
Document number: DxxxxR0<br/>
<a href="mailto:barry.revzin@gmail.com">Barry Revzin</a><br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a></br>
2016-10-12<br/>
</address>
<hr/>
<h1 align=center>Filling the gaps between structured bindings, aggregates, and template metaprogramming</h1>
<h2>Contents</h2>
<ul>
<li><a href="#Motivation">Motivation</a></li>
<li><a href="#Proposal">Proposal</a></li>
<li><a href="#Examples">Examples</a></li>
</ul>
<a name="Motivation"></a><h2>Motivation</h2>
<p>Recently, we have extended the concept of aggregates to include types with public base classes <sup><a href="#fn1" id="ref1">[1]</a></sup>. We have separately added support for structured bindings <sup><a href="#fn2" id="ref2">[2]</a></sup>. But there exists some drift between the two language features - structured bindings work on a subset of aggregates in a way that is inconsistent with the intent of either feature:
<blockquote><pre>
struct A { int x, y; }; // always been an aggregate
struct empty { };
struct B : empty { int x; }; // aggregate as of C++17
struct C : B { int y; }; // aggregate as of C++17
A makeA();
B makeB();
C makeC();
auto [x, y] = makeA(); // ok in C++17
auto [x] = makeB(); // ok in C++17, empty base is allowed
auto [x,y] = makeC(); // error: not an allowed case by default
</pre></blockquote>
Additionally, while there are now lots of types that we can decompose manually via structured bindings, most of these cannot be decomposed in a template metaprogramming context. The necessary is present in some cases but just not in others. Take various examples of simply having two <code>int</code>s in a type:
<blockquote><pre>
std::array<int, 2> a{1, 2};
std::tuple<int, int> b{3, 4};
std::pair<int, int> c{5, 6};
int d[2]{7, 8};
struct X { int a, b; };
X e{9, 10};
</pre></blockquote>
All of these can be decomposed into two <code>int</code>s directly with no further work. But only the first three can be passed to something like <code>std::apply</code>:
<blockquote><pre>
int sum(int a, int b) { return a+b; }
int s1 = std::apply(sum, a); // ok, s1 == 3
int s2 = std::apply(sum, b); // ok, s2 == 7
int s3 = std::apply(sum, c); // ok, s3 == 11
int s4 = std::apply(sum, d); // error
int s5 = std::apply(sum, e); // error
</pre></blockquote>
<p>We would have to write a bunch of code to make <code>e</code> <code>apply()</code>-able. But there is no amount of work we could do to make <code>d</code> <code>apply()</code>-able.
<p>We believe that structured bindings and template unpacking are two sides of the same coin and should be equivalently available.
<h3>Categories of Aggregates</h3>
<p>There are three categories of aggregates worth considering.
<ol>
<li> The easy case: raw arrays and those aggregates that have no base classes.
<blockquote><pre>
int array[2];
struct A { int x, y; };
</pre></blockquote>
<li> The medium case: aggregates that have at least one base class, but whose members are all direct members of a single type.
<blockquote><pre>
struct B : A { }; // all members are direct members of A
</pre></blockquote>
<li> The hard case: aggregates which have members that are direct members of different types.
<blockquote><pre>
struct C : B { char z; }; // two members are a direct member of A, the other of C
</pre></blockquote>
</ol>
There are two ways to automatically determine how to unpack an aggregate: yield all the <i>elements</i> of the aggregate as defined in [dcl.init.aggr] or flatten the aggregate and yield all the members in declaration order.
<blockquote><pre>
A makeA();
B makeB();
C makeC();
// unpacking into non-static data members
auto [a1,a2] = makeA(); // a1, a2 are ints
auto [b1,b2] = makeB(); // b1, b2 are ints
auto [c1,c2,c3] = makeC(); // c1, c2 are ints, c3 is a char
// unpacking into elements
auto [a1,a2] = makeA(); // a1, a2 are ints
auto [b1] = makeB(); // b1 is an A
auto [c1,c2] = makeC(); // c1 is a B, c2 is an char
</pre></blockquote>
The easy case is easy because both of these paths are equivalent. With the medium case, structured bindings chose the path of yielding all the members in declaration order - the paper itself was motivated by unpacking the data members, not the elements. We believe this decision to be the correct one - the decomposition of <code>B</code> and <code>C</code> above into elements is simply not useful.
<p>We want to extend that decision out to the hard case, the one currently not handled by structured bindings: flatten the aggregate and yield the non-static data members in declaration order.
<a name="Proposal"></a><h2>Proposal</h2>
<p>Building on P0197<sup><a href="#fn3" id="ref1">[3]</a></sup>, we would like to introduce the concept of a <i>tuple-like</i> type to be a type on which we can invoke the metafunction <code>std::tuple_size</code> to determine a number of elements and, for each valid index, get each element via either a member function template <code>std::get</code>. At the moment, the tuple-like types provided by the standard are <code>std::pair</code>, <code>std::tuple</code>, and <code>std::array</code>. But we would like to enlarge the universe of tuple-like types to include, out of the box, all aggregates.
<p>For raw arrays, we propose to introduce the template specializations:
<blockquote><pre>
template <class T, size_t N>
struct tuple_size<T[N]> : std::integral_constant<size_t, N> { };
template <<size_t Idx, class T, size_t N>
constexpr T& get(T (&array)[N]) {
static_assert(Idx < N);
return array[Idx];
}
</pre></blockquote>
<p>For aggregates of class type <code>T</code>, to instantiate the class template <code>std::tuple_size<T></code>, if no prior specialization can be found, we propose to synthesize a new specialization which inherits from <code>std::integral_constant<size_t, N></code>, where <code>N</code> is the number of non-static data members. Similarly, to instantiate the function template <code>std::get<N>(T)</code>, if no overload can be found, we propose synthesize a new overload which returns the <code>N</code>th non-static data member.
<p>For example, for the type hierarchy from earlier
<blockquote><pre>
struct A { int x, y; };
struct B : A { };
struct C : B { char z; };
</pre></blockquote>
we would synthesize:
<blockquote><pre>
namespace std {
template <> struct tuple_size<A> : std::integral_constant<std::size_t, 2> { };
template <> struct tuple_size<B> : std::integral_constant<std::size_t, 2> { };
template <> struct tuple_size<C> : std::integral_constant<std::size_t, 3> { };
template <> struct tuple_element<0, A> { using type = int; };
template <> struct tuple_element<1, A> { using type = int; };
template <> struct tuple_element<0, B> { using type = int; };
template <> struct tuple_element<1, B> { using type = int; };
template <> struct tuple_element<0, C> { using type = int; };
template <> struct tuple_element<1, C> { using type = int; };
template <> struct tuple_element<2, C> { using type = char; };
template <std::size_t I>
auto& get(A& a) {
static_assert(I < 2);
if constexpr (I == 0) return a.x;
else if constexpr (I == 1) return a.y;
}
template <std::size_t I>
auto& get(B& b) {
static_assert(I < 2);
if constexpr (I == 0) return b.x;
else if constexpr (I == 1) return b.y;
}
template <std::size_t I>
auto& get(C& c) {
static_assert(I < 3);
if constexpr (I == 0) return c.x;
else if constexpr (I == 1) return c.y;
else if constexpr (I == 2) return c.z;
}
// + const equivalents, etc.
}
</pre></blockquote>
<p>Note that specializations are only synthesized if they are not found, so if a programmer wants to unpack a type in the non-default way, this is still possible.
<p>The effect of this proposal would be to simplify the current wording for how to understand a decomposition declaration. A type must be tuple-like to be decomposable. There is now just the one case instead of three. Additionally that's a <i>large</i> amount of boilerplate code that wouldn't need to be written to let these types be both bindable and usable in a metaprogramming context!
<a name="Examples"></a><h2>Examples</h2>
With the new definition of tuple-like and the implicit synthesize of <code>tuple_size</code> and <code>get</code> for all aggregates, the following all just works:
<blockquote><pre>
struct A { int i; char c; };
struct B : A { double d; };
static_assert(tuple_size<A>{} == 2);
static_assert(tuple_size<B>{} == 3);
// picking elements
A a{22, 'w'};
int first = std::get<0>(a);
char second = std::get<1>(a);
assert(first == 22 && second = 'w');
// decomposing arbitrary aggregates
auto [i,c,d] = B{42, 'x', 3.14};
// applying aggregates
auto first = [](auto&& x, auto&&... ) { return x; }
int x = std::apply(first, A{17, 'j'});
assert(x == 17);
// tuple-like array operations
int raw[3]{1, 2, 3};
int y = std::apply(first, raw);
assert(y == 1);
int z = std::get<2>(raw);
assert(z == 3);
int j = std::get<4>(raw); // error: bounds
// tuple_cat all the things
int others[2]{4, 5};
std::tuple<int,int,int,int,int,int,char> everything = std::tuple_cat(raw, others, a);
</pre></blockquote>
<p>
<span id="fn1">[1] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html">Extension to aggregate initialization (P00171R1)</a></span>
<p><span id="fn2">[2] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0144r2.pdf">Structured Bindings (P0144R2)</a></span>
<p><span id="fn3">[3] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0197r0.pdf">Default Tuple-like Access (P0197R0)</a></span>
</body>
</html>
------=_Part_977_880798798.1476646307834--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 16 Oct 2016 12:44:58 -0700 (PDT)
Raw View
------=_Part_1400_974794338.1476647098614
Content-Type: multipart/alternative;
boundary="----=_Part_1401_1256819566.1476647098614"
------=_Part_1401_1256819566.1476647098614
Content-Type: text/plain; charset=UTF-8
On Sunday, October 16, 2016 at 3:31:48 PM UTC-4, Barry Revzin wrote:
>
> Here's a better draft where we're clarifying the problem set and dividing
> the world of types into three cases. The paper isn't about aggregate
> initialization - it's about wanting the machinery implicit to structured
> bindings available in a metaprogramming context and wanting that machinery
> to by default apply to more kinds of types.
>
First, your proposal needs to use the term "aggregate" correctly.
Structured binding is not restricted to aggregates. The definition of
"aggregate" requires that the type has no constructors. SB doesn't care if
the type has constructors or not; it only cares about publicly accessible
member variables and whether they're all declared in the same type.
So there are types which are aggregates, and there are types which can use
structured binding. At present, neither category is a subset of the other.
Second, these really should be two different proposals. One being having a
generic way to iterate over SB-capable types that don't explicitly
implement the interface, with the other being an expansion of the
requirements of SB-capable types.
Lastly, I think having a formal name for SB-capable types (that is, types
that would work without explicitly declaring the interface) would be a good
idea. "Tuple-like" being the obvious one, but also "value sequence" or
perhaps something else. Whatever it is, it's a concept that really needs a
name.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ccec5bd4-9545-4f02-8645-981e62c2c896%40isocpp.org.
------=_Part_1401_1256819566.1476647098614
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, October 16, 2016 at 3:31:48 PM UTC-4, Barry Rev=
zin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Her=
e's a better draft where we're clarifying the problem set and divid=
ing the world of types into three cases. The paper isn't about aggregat=
e initialization - it's about wanting the machinery implicit to structu=
red bindings available in a metaprogramming context and wanting that machin=
ery to by default apply to more kinds of types.=C2=A0</div></blockquote><di=
v><br>First, your proposal needs to use the term "aggregate" corr=
ectly. Structured binding is not restricted to aggregates. The definition o=
f "aggregate" requires=20
that the type has no constructors. SB doesn't care if the type has=20
constructors or not; it only cares about publicly accessible member=20
variables and whether they're all declared in the same type.<br><br>So =
there are types which are aggregates, and there are types which can use str=
uctured binding. At present, neither category is a subset of the other.<br>=
<br>Second, these really should be two different proposals. One being havin=
g a generic way to iterate over SB-capable types that don't explicitly =
implement the interface, with the other being an expansion of the requireme=
nts of SB-capable types.<br><br>Lastly, I think having a formal name for SB=
-capable types (that is, types that would work without explicitly declaring=
the interface) would be a good idea. "Tuple-like" being the obvi=
ous one, but also "value sequence" or perhaps something else. Wha=
tever it is, it's a concept that really needs a name.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ccec5bd4-9545-4f02-8645-981e62c2c896%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ccec5bd4-9545-4f02-8645-981e62c2c896=
%40isocpp.org</a>.<br />
------=_Part_1401_1256819566.1476647098614--
------=_Part_1400_974794338.1476647098614--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 16 Oct 2016 23:18:04 +0200
Raw View
This is a multi-part message in MIME format.
--------------07F32C7640A73F34D31A8565
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 16/10/2016 =C3=A0 21:44, Nicol Bolas a =C3=A9crit :
> On Sunday, October 16, 2016 at 3:31:48 PM UTC-4, Barry Revzin wrote:
>
> Here's a better draft where we're clarifying the problem set and
> dividing the world of types into three cases. The paper isn't
> about aggregate initialization - it's about wanting the machinery
> implicit to structured bindings available in a metaprogramming
> context and wanting that machinery to by default apply to more
> kinds of types.
>
>
> First, your proposal needs to use the term "aggregate" correctly.=20
> Structured binding is not restricted to aggregates. The definition of=20
> "aggregate" requires that the type has no constructors. SB doesn't=20
> care if the type has constructors or not; it only cares about publicly=20
> accessible member variables and whether they're all declared in the=20
> same type.
>
> So there are types which are aggregates, and there are types which can=20
> use structured binding. At present, neither category is a subset of=20
> the other.
>
> Second, these really should be two different proposals. One being=20
> having a generic way to iterate over SB-capable types that don't=20
> explicitly implement the interface, with the other being an expansion=20
> of the requirements of SB-capable types.
>
> Lastly, I think having a formal name for SB-capable types (that is,=20
> types that would work without explicitly declaring the interface)=20
> would be a good idea. "Tuple-like" being the obvious one, but also=20
> "value sequence" or perhaps something else. Whatever it is, it's a=20
> concept that really needs a name.
Product Type?
https://github.com/viboes/std-make/blob/master/doc/proposal/reflection/p032=
7r1.md
Vicente
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/94cbea29-edd8-9b46-a2f4-20aac92a6852%40wanadoo.f=
r.
--------------07F32C7640A73F34D31A8565
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 16/10/2016 =C3=A0 21:44, Nicol Bolas =
a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:ccec5bd4-9545-4f02-8645-981e62c2c896@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">On Sunday, October 16, 2016 at 3:31:48 PM UTC-4,
Barry Revzin wrote:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div dir=3D"ltr">Here's a better draft where we're clarifying
the problem set and dividing the world of types into three
cases. The paper isn't about aggregate initialization - it's
about wanting the machinery implicit to structured bindings
available in a metaprogramming context and wanting that
machinery to by default apply to more kinds of types.=C2=A0</di=
v>
</blockquote>
<div><br>
First, your proposal needs to use the term "aggregate"
correctly. Structured binding is not restricted to aggregates.
The definition of "aggregate" requires that the type has no
constructors. SB doesn't care if the type has constructors or
not; it only cares about publicly accessible member variables
and whether they're all declared in the same type.<br>
<br>
So there are types which are aggregates, and there are types
which can use structured binding. At present, neither category
is a subset of the other.<br>
<br>
Second, these really should be two different proposals. One
being having a generic way to iterate over SB-capable types
that don't explicitly implement the interface, with the other
being an expansion of the requirements of SB-capable types.<br>
<br>
Lastly, I think having a formal name for SB-capable types
(that is, types that would work without explicitly declaring
the interface) would be a good idea. "Tuple-like" being the
obvious one, but also "value sequence" or perhaps something
else. Whatever it is, it's a concept that really needs a name.<br=
>
</div>
</div>
</blockquote>
Product Type?<br>
<br>
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/viboes/std-ma=
ke/blob/master/doc/proposal/reflection/p0327r1.md">https://github.com/viboe=
s/std-make/blob/master/doc/proposal/reflection/p0327r1.md</a><br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/94cbea29-edd8-9b46-a2f4-20aac92a6852%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/94cbea29-edd8-9b46-a2f4-20aac92a6852=
%40wanadoo.fr</a>.<br />
--------------07F32C7640A73F34D31A8565--
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Mon, 17 Oct 2016 05:36:16 -0700 (PDT)
Raw View
------=_Part_1597_1779732791.1476707777002
Content-Type: multipart/alternative;
boundary="----=_Part_1598_402029648.1476707777002"
------=_Part_1598_402029648.1476707777002
Content-Type: text/plain; charset=UTF-8
>
>
>
> First, your proposal needs to use the term "aggregate" correctly.
> Structured binding is not restricted to aggregates. The definition of
> "aggregate" requires that the type has no constructors. SB doesn't care if
> the type has constructors or not; it only cares about publicly accessible
> member variables and whether they're all declared in the same type.
>
>
This was a bad misconception of mine... I thought SB was restricted to
aggregates. Will have to rewrite a bunch of stuff...
>
> So there are types which are aggregates, and there are types which can use
> structured binding. At present, neither category is a subset of the other.
>
> Second, these really should be two different proposals. One being having a
> generic way to iterate over SB-capable types that don't explicitly
> implement the interface, with the other being an expansion of the
> requirements of SB-capable types.
>
>
I think the two concepts are very closely linked - SB is unpacking a
"thing" into its components manually by providing names for all of them,
and tuple_size/tuple_element/get is unpacking a "thing" into its components
by index. Plus SB piggybacks off of the latter, so I think it makes sense
to keep them together.
>
> Lastly, I think having a formal name for SB-capable types (that is, types
> that would work without explicitly declaring the interface) would be a good
> idea. "Tuple-like" being the obvious one, but also "value sequence" or
> perhaps something else. Whatever it is, it's a concept that really needs a
> name.
>
> Product Type?
>
>
> https://github.com/viboes/std-make/blob/master/doc/proposal/reflection/p0327r1.md
> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fviboes%2Fstd-make%2Fblob%2Fmaster%2Fdoc%2Fproposal%2Freflection%2Fp0327r1.md&sa=D&sntz=1&usg=AFQjCNGd_CgOnTvYwqB9-85UsAPQDo9ctw>
>
> Vicente
>
There should definitely be a name for this, I have no view on what that
should be. All of these sound fine to me.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/6bac6734-b81c-46c8-8472-9351fada5863%40isocpp.org.
------=_Part_1598_402029648.1476707777002
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=
=3D"#FFFFFF" text=3D"#000000"><br><blockquote type=3D"cite"><div dir=3D"ltr=
">
<div><br>
First, your proposal needs to use the term "aggregate"
correctly. Structured binding is not restricted to aggregates.
The definition of "aggregate" requires that the type ha=
s no
constructors. SB doesn't care if the type has constructors or
not; it only cares about publicly accessible member variables
and whether they're all declared in the same type.<br></div><=
/div></blockquote></div></blockquote><div><br></div><div>This was a bad mis=
conception of mine... I thought SB was restricted to aggregates. Will have =
to rewrite a bunch of stuff...=C2=A0</div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000"><blo=
ckquote type=3D"cite"><div dir=3D"ltr"><div>
<br>
So there are types which are aggregates, and there are types
which can use structured binding. At present, neither category
is a subset of the other.<br>
<br>
Second, these really should be two different proposals. One
being having a generic way to iterate over SB-capable types
that don't explicitly implement the interface, with the other
being an expansion of the requirements of SB-capable types.<br></=
div></div></blockquote></div></blockquote><div><br></div><div>I think the t=
wo concepts are very closely linked - SB is unpacking a "thing" i=
nto its components manually by providing names for all of them, and tuple_s=
ize/tuple_element/get is unpacking a "thing" into its components =
by index. Plus SB piggybacks off of the latter, so I think it makes sense t=
o keep them together.=C2=A0</div><div>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000"><blockquote t=
ype=3D"cite"><div dir=3D"ltr"><div>
<br>
Lastly, I think having a formal name for SB-capable types
(that is, types that would work without explicitly declaring
the interface) would be a good idea. "Tuple-like" being=
the
obvious one, but also "value sequence" or perhaps somet=
hing
else. Whatever it is, it's a concept that really needs a name=
..<br>
</div>
</div>
</blockquote>
Product Type?<br>
<br>
<a href=3D"https://www.google.com/url?q=3Dhttps%3A%2F%2Fgithub.com%2Fviboes=
%2Fstd-make%2Fblob%2Fmaster%2Fdoc%2Fproposal%2Freflection%2Fp0327r1.md&=
sa=3DD&sntz=3D1&usg=3DAFQjCNGd_CgOnTvYwqB9-85UsAPQDo9ctw" target=3D=
"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.googl=
e.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fviboes%2Fstd-make%2Fblob%2Fmaster=
%2Fdoc%2Fproposal%2Freflection%2Fp0327r1.md\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNGd_CgOnTvYwqB9-85UsAPQDo9ctw';return true;" onclick=3D"this.hr=
ef=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fviboes=
%2Fstd-make%2Fblob%2Fmaster%2Fdoc%2Fproposal%2Freflection%2Fp0327r1.md\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGd_CgOnTvYwqB9-85UsAPQDo9ctw';retur=
n true;">https://github.com/viboes/std-<wbr>make/blob/master/doc/proposal/<=
wbr>reflection/p0327r1.md</a><br>
<br>
Vicente<br></div></blockquote><div><br></div><div>There should definite=
ly be a name for this, I have no view on what that should be. All of these =
sound fine to me.=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/6bac6734-b81c-46c8-8472-9351fada5863%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6bac6734-b81c-46c8-8472-9351fada5863=
%40isocpp.org</a>.<br />
------=_Part_1598_402029648.1476707777002--
------=_Part_1597_1779732791.1476707777002--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 17 Oct 2016 08:23:00 -0700 (PDT)
Raw View
------=_Part_1760_1933535871.1476717781045
Content-Type: multipart/alternative;
boundary="----=_Part_1761_646953694.1476717781046"
------=_Part_1761_646953694.1476717781046
Content-Type: text/plain; charset=UTF-8
On Monday, October 17, 2016 at 8:36:17 AM UTC-4, Barry Revzin wrote:
>
> So there are types which are aggregates, and there are types which can use
>> structured binding. At present, neither category is a subset of the other.
>>
>> Second, these really should be two different proposals. One being having
>> a generic way to iterate over SB-capable types that don't explicitly
>> implement the interface, with the other being an expansion of the
>> requirements of SB-capable types.
>>
>>
> I think the two concepts are very closely linked - SB is unpacking a
> "thing" into its components manually by providing names for all of them,
> and tuple_size/tuple_element/get is unpacking a "thing" into its components
> by index. Plus SB piggybacks off of the latter, so I think it makes sense
> to keep them together.
>
Related perhaps, but ultimately different. The reason to want implicitly
SB-capable types to be able to be metaprogrammatically iterable has nothing
to do with structured binding itself. It's not like you'd be implementing
structured binding based on such entrypoints, nor would you redefine SB to
work in terms of such implicit entrypoints. We want to use the existing SB
wording, where for implicitly SB-capable types we get a magical
compiler-based transformation of names into member field accessors. We
don't want to turn them into references acquired via `get` or whatever.
So the metaprogramming iteration proposal doesn't affect SB directly.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/13b04913-7ce9-4945-b4bd-d983e530a6c4%40isocpp.org.
------=_Part_1761_646953694.1476717781046
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, October 17, 2016 at 8:36:17 AM UTC-4, Barry Rev=
zin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" te=
xt=3D"#000000"><blockquote type=3D"cite"><div dir=3D"ltr"><div>
=20
So there are types which are aggregates, and there are types
which can use structured binding. At present, neither category
is a subset of the other.<br>
<br>
Second, these really should be two different proposals. One
being having a generic way to iterate over SB-capable types
that don't explicitly implement the interface, with the other
being an expansion of the requirements of SB-capable types.<br></=
div></div></blockquote></div></blockquote><div><br></div><div>I think the t=
wo concepts are very closely linked - SB is unpacking a "thing" i=
nto its components manually by providing names for all of them, and tuple_s=
ize/tuple_element/get is unpacking a "thing" into its components =
by index. Plus SB piggybacks off of the latter, so I think it makes sense t=
o keep them together.=C2=A0</div></div></blockquote><div><br>Related perhap=
s, but ultimately different. The reason to want implicitly SB-capable types=
to be able to be metaprogrammatically iterable has nothing to do with stru=
ctured binding itself. It's not like you'd be implementing structur=
ed binding based on such entrypoints, nor would you redefine SB to work in =
terms of such implicit entrypoints. We want to use the existing SB wording,=
where for implicitly SB-capable types we get a magical compiler-based tran=
sformation of names into member field accessors. We don't want to turn =
them into references acquired via `get` or whatever.<br><br>So the metaprog=
ramming iteration proposal doesn't affect SB directly.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/13b04913-7ce9-4945-b4bd-d983e530a6c4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/13b04913-7ce9-4945-b4bd-d983e530a6c4=
%40isocpp.org</a>.<br />
------=_Part_1761_646953694.1476717781046--
------=_Part_1760_1933535871.1476717781045--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 17 Oct 2016 18:24:46 +0300
Raw View
On 17 October 2016 at 18:23, Nicol Bolas <jmckesson@gmail.com> wrote:
>> I think the two concepts are very closely linked - SB is unpacking a
>> "thing" into its components manually by providing names for all of them, and
>> tuple_size/tuple_element/get is unpacking a "thing" into its components by
>> index. Plus SB piggybacks off of the latter, so I think it makes sense to
>> keep them together.
>
>
> Related perhaps, but ultimately different. The reason to want implicitly
> SB-capable types to be able to be metaprogrammatically iterable has nothing
> to do with structured binding itself. It's not like you'd be implementing
> structured binding based on such entrypoints, nor would you redefine SB to
> work in terms of such implicit entrypoints. We want to use the existing SB
> wording, where for implicitly SB-capable types we get a magical
> compiler-based transformation of names into member field accessors. We don't
> want to turn them into references acquired via `get` or whatever.
>
> So the metaprogramming iteration proposal doesn't affect SB directly.
Save for the part that we need something like this proposal to be able
to explicitly check the types
of the bindings in the binding expression, since the language
currently doesn't allow doing that.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUYrBqKnfHMCSxbzH%3DXuNGm6G1rJngSCunY8JRhTOvcE2Q%40mail.gmail.com.
.