Topic: n4428 and Tuple-like access interface reflection
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 29 Dec 2015 01:48:55 +0100
Raw View
This is a multi-part message in MIME format.
--------------070409020409080900010803
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Adding std-proposals
Vicente
Le 20/12/2015 20:27, Vicente J. Botet Escriba a =C3=A9crit :
> Hi,
>
> Based on the reflection traitsfrom n4428I would like to have the=20
> following tuple like traits specializations for a POD struct C.
>
> template <>
> struct tuple_size<C> :=20
> size_t_constant<std::class_traits<C>::class_members::size> {};
>
> template <size_t N>
> struct tuple_element<N, C> :=20
> id<decltype(std::declval<C>().*declval<std::class_traits<C>::base_members=
::get<N>::pointer>())>=20
> {};
>
> template <size_t N>
> requires N < std::class_traits<C>::class_members::size
> constexpr tuple_element_t<N,C>& get(C & that) noexcept
> {
> std::class_traits<C>::base_members::get<N>::pointer pm;
> return that.*pm;
> }
>
> template <size_t N>
> requires N < std::class_traits<C>::class_members::size
> constexpr const tuple_element_t<N,C>& get(const C & that) noexcept
> {
> std::class_traits<C>::base_members::get<N>::pointer pm;
> return that.*pm;
> }
>
> template <size_t N>
> requires N < std::class_traits<C>::class_members::size
> constexpr tuple_element_t<N,C>&& get(C && that) noexcept
> {
> std::class_traits<C>::base_members::get<N>::pointer pm;
> return std::forward<tuple_element_t<N,C>&&>(that.*pm);
> }
>
> /// the same for get with a type
>
> However, I would like to do it for some more classes C1, C2, ...
>
> I have added a trait tuple_like that states if I want the generation
>
> template <class T>
> struct tuple_like: false_type {};
>
> but I don't see how to make the specialization conditional to this=20
> traits without adding an Enabler parameter
>
> template <class T, class Enabler=3Dvoid>
> struct tuple_size;
> template <size_t N, class T, class Enabler=3Dvoid>
> struct tuple_element;
>
> Is there a way without changing the std::tuple_size and=20
> std::tuple_element template parameters?
> What would be the the correct way to do that?
>
> Vicente=20
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------070409020409080900010803
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">Adding std-proposals<br>
Vicente<br>
<br>
Le 20/12/2015 20:27, Vicente J. Botet Escriba a =C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:56770133.7070701@wanadoo.fr" type=3D"cite">
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf=
-8">
<font size=3D"+1">Hi, <br>
<br>
</font><font size=3D"+1"><c><font size=3D"+1">Based on the reflection
traits</font></c></font><font size=3D"+1"><c><font size=3D"+1">
from n4428</font></c></font><font size=3D"+1"><c><font
size=3D"+1"><c> I would like to have the following </c></font><=
font
size=3D"+1"><c><font size=3D"+1">tuple like traits
specializations </font></c></font></c></font><font
size=3D"+1"><c><font size=3D"+1"><c><font size=3D"+1"><font size=3D=
"+1">for
a POD struct C. </font><font size=3D"+1"><c><font
size=3D"+1"><br>
</font></c></font></font></c></font> <br>
template <><br>
struct tuple_size<C> : size_t_constant<</c></font><font
size=3D"+1"><c>std::class_traits<c><C>::class_members::size</=
c>>
{};<br>
<br>
</c></font><font size=3D"+1"><c><font size=3D"+1"><c>template
<size_t N><br>
struct tuple_element<N, C> : id<</c></font><font
size=3D"+1"><c>decltype(std::declval<C>().*declval<std=
::class_traits<c><C>::base_</c></c></font></c></font><font
size=3D"+1"><c><font size=3D"+1"><c><c><font size=3D"+1">members</f=
ont>::get<N>::pointer</c>>())>
{};<br>
</c></font></c></font><br>
<font size=3D"+1"><c><font size=3D"+1"><font size=3D"+1">template
<size_t N><br>
requires N < </font></font></c></font><font size=3D"+1"><c=
><font
size=3D"+1"><font size=3D"+1"><font size=3D"+1"><c>std::class_t=
raits<c><C>::class_members::size<br>
</c></c></font>=C2=A0</font></font>constexpr
tuple_element_t<N,C>& get(C & that) noexcept <br>
{<br>
</c></font><font size=3D"+1"><c><font size=3D"+1"><c><font size=3D"=
+1"><c>=C2=A0=C2=A0=C2=A0
std::class_traits<c><C>::base_</c></c></font></c></=
font><font
size=3D"+1"><c><font size=3D"+1"><c><c><font size=3D"+1">member=
s</font>::get<N>::pointer</c></c></font></c></font>
pm; =C2=A0 </c></font><br>
<font size=3D"+1"><c><font size=3D"+1">=C2=A0=C2=A0=C2=A0 return that=
</font>.*pm;<br>
}<br>
</c></font><br>
<font size=3D"+1"><c><font size=3D"+1"><c><font size=3D"+1"><font
size=3D"+1">template <size_t N><br>
</font></font></c></font></c></font><font size=3D"+1"><c><f=
ont
size=3D"+1"><c><font size=3D"+1"><c><font size=3D"+1"><font
size=3D"+1">requires N < </font></font></c></font>=
<font
size=3D"+1"><c><font size=3D"+1"><font size=3D"+1"><font
size=3D"+1"><c>std::class_traits<c><C>::class=
_members::size<br>
</c></c></font></font></font></c></font>constexpr
const tuple_element_t<N,C>& get(</c></font></c></fo=
nt><font
size=3D"+1"><c><font size=3D"+1"><c><font size=3D"+1"><font size=3D=
"+1">const
</font></font>C & that) noexcept <br>
{<br>
</c></font><font size=3D"+1"><c><font size=3D"+1"><c><font
size=3D"+1"><c>=C2=A0=C2=A0=C2=A0 std::class_traits<c>&=
lt;C>::base_</c></c></font></c></font><font
size=3D"+1"><c><font size=3D"+1"><c><c><font size=3D"+1">me=
mbers</font>::get<N>::pointer</c></c></font></c></font>
pm; =C2=A0 </c></font><br>
<font size=3D"+1"><c><font size=3D"+1">=C2=A0=C2=A0=C2=A0 return =
that</font>.*pm;<br>
}<br>
</c></font></c></font><br>
<font size=3D"+1"><c><font size=3D"+1"><font size=3D"+1">template
<size_t N><br>
requires N < </font></font></c></font><font size=3D"+1"><c=
><font
size=3D"+1"><font size=3D"+1"><font size=3D"+1"><c>std::class_t=
raits<c><C>::class_members::size<br>
</c></c></font></font></font>constexpr
tuple_element_t<N,C>&& get(C && that)
noexcept <br>
{<br>
</c></font><font size=3D"+1"><c><font size=3D"+1"><c><font size=3D"=
+1"><c>=C2=A0=C2=A0=C2=A0
std::class_traits<c><C>::base_</c></c></font></c></=
font><font
size=3D"+1"><c><font size=3D"+1"><c><c><font size=3D"+1">member=
s</font>::get<N>::pointer</c></c></font></c></font>
pm; =C2=A0 </c></font><br>
<font size=3D"+1"><c><font size=3D"+1">=C2=A0=C2=A0=C2=A0 return std:=
:forward<</font></c></font><font
size=3D"+1"><c><font size=3D"+1"><font size=3D"+1">tuple_element_t&=
lt;N,C></font>&&>(that</font>.*pm);<br>
}<br>
<br>
/// the same for get with a type<br>
<br>
However, I would like to do it for some more classes C1, C2,
...<br>
<br>
I have added a trait </c></font><font size=3D"+1"><c><font
size=3D"+1"><font size=3D"+1">tuple_like </font></font>that
states if I want the generation <br>
</c></font><br>
<font size=3D"+1"><font size=3D"+1">template <class T><br>
struct tuple_like: false_type {};<br>
</font></font><br>
<font size=3D"+1">but I don't see how to make the specialization
conditional to this traits without adding an Enabler parameter<br>
<br>
</font><font size=3D"+1"><c><font size=3D"+1">=C2=A0=C2=A0=C2=A0 temp=
late <class
T, class Enabler=3Dvoid><br>
</font></c></font><font size=3D"+1"><c><font size=3D"+1">=C2=A0=
=C2=A0=C2=A0
struct tuple_size;<br>
</font></c></font><font size=3D"+1"><c><font size=3D"+1"><font
size=3D"+1"><font size=3D"+1">=C2=A0=C2=A0=C2=A0 template <=
;size_t N, </font></font></font></c></font><font
size=3D"+1"><c><font size=3D"+1"><font size=3D"+1"><font size=3D"+1=
"><font
size=3D"+1"><font size=3D"+1">class T, class Enabler=3Dvo=
id</font></font>><br>
=C2=A0=C2=A0=C2=A0 struct tuple_element;<br>
<br>
</font></font></font></c></font><font size=3D"+1"><c><font
size=3D"+1">Is there a way without changing the
std::tuple_size and </font></c></font><font size=3D"+1"><c><fon=
t
size=3D"+1"><font size=3D"+1"><font size=3D"+1">std::</font></f=
ont>tuple_element
template parameters?<br>
</font></c></font><font size=3D"+1"><c><font size=3D"+1"><font
size=3D"+1"><c>What would be the the correct way to do that?<=
/c></font><font
size=3D"+1"><c><br>
</c></font><font size=3D"+1"><c></c></font> <br>
Vicente</font></c></font> </blockquote>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------070409020409080900010803--
.
Author: Casey Carter <cartec69@gmail.com>
Date: Mon, 28 Dec 2015 21:08:25 -0800 (PST)
Raw View
------=_Part_55_1173483533.1451365706073
Content-Type: multipart/alternative;
boundary="----=_Part_56_1528315012.1451365706074"
------=_Part_56_1528315012.1451365706074
Content-Type: text/plain; charset=UTF-8
On Monday, December 28, 2015 at 6:48:58 PM UTC-6, Vicente J. Botet Escriba
wrote:
>
> I have added a trait tuple_like that states if I want the generation
>
> template <class T>
> struct tuple_like: false_type {};
>
> but I don't see how to make the specialization conditional to this traits
> without adding an Enabler parameter
>
> template <class T, class Enabler=void>
> struct tuple_size;
> template <size_t N, class T, class Enabler=void>
> struct tuple_element;
>
> Is there a way without changing the std::tuple_size and std::tuple_element
> template parameters?
> What would be the the correct way to do that?
>
>
template <class T>
requires tuple_like<T>::value
struct tuple_size<T> : /* ... */;
template <size_t N, class T>
requires tuple_like<T>::value
struct tuple_element<N, T> : /* ... */;
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_56_1528315012.1451365706074
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br>On Monday, December 28, 2015 at 6:48:58 PM UTC-6, Vicente J. Botet Escr=
iba 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">
<blockquote type=3D"cite"><font size=3D"+1">I have added a trait </font=
><font size=3D"+1"><font size=3D"+1"><font size=3D"+1">tuple_like </font></=
font>that
states if I want the generation <br>
</font><br>
<font size=3D"+1"><font size=3D"+1">template <class T><br>
struct tuple_like: false_type {};<br>
</font></font><br>
<font size=3D"+1">but I don't see how to make the specialization
conditional to this traits without adding an Enabler parameter<br>
<br>
</font><font size=3D"+1"><font size=3D"+1">=C2=A0=C2=A0=C2=A0 templat=
e <class
T, class Enabler=3Dvoid><br>
</font></font><font size=3D"+1"><font size=3D"+1">=C2=A0=C2=A0=C2=
=A0
struct tuple_size;<br>
</font></font><font size=3D"+1"><font size=3D"+1"><font size=3D"+=
1"><font size=3D"+1">=C2=A0=C2=A0=C2=A0 template <size_t N, </font></fon=
t></font></font><font size=3D"+1"><font size=3D"+1"><font size=3D"+1"><font=
size=3D"+1"><font size=3D"+1"><font size=3D"+1">class T, class Enabler=3Dv=
oid</font></font>><br>
=C2=A0=C2=A0=C2=A0 struct tuple_element;<br>
<br>
</font></font></font></font><font size=3D"+1"><font size=3D"+=
1">Is there a way without changing the
std::tuple_size and </font></font><font size=3D"+1"><font size=
=3D"+1"><font size=3D"+1"><font size=3D"+1">std::</font></font>tuple_elemen=
t
template parameters?<br>
</font></font><font size=3D"+1"><font size=3D"+1"><font size=3D"+=
1">What would be the the correct way to do that?</font></font></font></bloc=
kquote></div></blockquote><div><br></div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templ=
ate</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: #008;" class=3D"styled-by-prettify">class</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>requires tuple_like</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">>::</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">value<br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> tuple_size</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">T</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">:</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">/* ... */</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">template</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;" cl=
ass=3D"styled-by-prettify">size_t N</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>requires=
tuple_like</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
><</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">>::</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">value<br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> tuple_element</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">N</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">/* ... */=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code><=
/div><div><div><br><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_56_1528315012.1451365706074--
------=_Part_55_1173483533.1451365706073--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 29 Dec 2015 11:35:28 +0100
Raw View
This is a multi-part message in MIME format.
--------------030704070707040309010206
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 29/12/2015 06:08, Casey Carter a =C3=A9crit :
>
> On Monday, December 28, 2015 at 6:48:58 PM UTC-6, Vicente J. Botet=20
> Escriba wrote:
>
>> I have added a trait tuple_like that states if I want the generation
>>
>> template <class T>
>> struct tuple_like: false_type {};
>>
>> but I don't see how to make the specialization conditional to
>> this traits without adding an Enabler parameter
>>
>> template <class T, class Enabler=3Dvoid>
>> struct tuple_size;
>> template <size_t N, class T, class Enabler=3Dvoid>
>> struct tuple_element;
>>
>> Is there a way without changing the std::tuple_size and
>> std::tuple_element template parameters?
>> What would be the the correct way to do that?
>
>
> |
> template<classT>
> requires tuple_like<T>::value
> structtuple_size<T>:/* ... */;
>
>
> template<size_t N,classT>
> requires tuple_like<T>::value
> structtuple_element<N,T>:/* ... */;
>
> |
>
>
>
And without Concepts?
In addition to N4428, do we want that the reflection library request the=20
compiler to generate these tuple-like access?
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------030704070707040309010206
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 29/12/2015 06:08, Casey Carter a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:0c101390-8938-483d-91a8-e1f4a83bdefb@isocpp.org"
type=3D"cite"><br>
On Monday, December 28, 2015 at 6:48:58 PM UTC-6, 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;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite"><font size=3D"+1">I have added a trait =
</font><font
size=3D"+1"><font size=3D"+1"><font size=3D"+1">tuple_like </=
font></font>that
states if I want the generation <br>
</font><br>
<font size=3D"+1"><font size=3D"+1">template <class T><br=
>
struct tuple_like: false_type {};<br>
</font></font><br>
<font size=3D"+1">but I don't see how to make the
specialization conditional to this traits without adding
an Enabler parameter<br>
<br>
</font><font size=3D"+1"><font size=3D"+1">=C2=A0=C2=A0=C2=A0 t=
emplate
<class T, class Enabler=3Dvoid><br>
</font></font><font size=3D"+1"><font size=3D"+1">=C2=A0=C2=
=A0=C2=A0 struct
tuple_size;<br>
</font></font><font size=3D"+1"><font size=3D"+1"><font
size=3D"+1"><font size=3D"+1">=C2=A0=C2=A0=C2=A0 template=
<size_t N, </font></font></font></font><font
size=3D"+1"><font size=3D"+1"><font size=3D"+1"><font size=3D=
"+1"><font
size=3D"+1"><font size=3D"+1">class T, class
Enabler=3Dvoid</font></font>><br>
=C2=A0=C2=A0=C2=A0 struct tuple_element;<br>
<br>
</font></font></font></font><font size=3D"+1"><font
size=3D"+1">Is there a way without changing the
std::tuple_size and </font></font><font size=3D"+1"><font
size=3D"+1"><font size=3D"+1"><font size=3D"+1">std::</font=
></font>tuple_element
template parameters?<br>
</font></font><font size=3D"+1"><font size=3D"+1"><font
size=3D"+1">What would be the the correct way to do
that?</font></font></font></blockquote>
</div>
</blockquote>
<div><br>
</div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187,
187); word-wrap: break-word; background-color: rgb(250, 250,
250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #008;"
class=3D"styled-by-prettify">template</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span
style=3D"color: #660;" class=3D"styled-by-prettify"><</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">class</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> T</span>=
<span
style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
requires tuple_like</span><span style=3D"color: #660;"
class=3D"styled-by-prettify"><</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">T</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">>::</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify">value<br>
</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">struct</span><span
style=3D"color: #000;" class=3D"styled-by-prettify">
tuple_size</span><span style=3D"color: #660;"
class=3D"styled-by-prettify"><</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">T</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><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"> </span><=
span
style=3D"color: #800;" 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>
<br>
<br>
</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">template</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span
style=3D"color: #660;" class=3D"styled-by-prettify"><</spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify">size_t N<=
/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">class</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> T</span>=
<span
style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
requires tuple_like</span><span style=3D"color: #660;"
class=3D"styled-by-prettify"><</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">T</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">>::</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify">value<br>
</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">struct</span><span
style=3D"color: #000;" class=3D"styled-by-prettify">
tuple_element</span><span style=3D"color: #660;"
class=3D"styled-by-prettify"><</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">N</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span
style=3D"color: #000;" class=3D"styled-by-prettify"> T</span>=
<span
style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><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"> </span><=
span
style=3D"color: #800;" 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: #000;" class=3D"styled-by-prettify=
"><br>
</span></div>
</code></div>
<div>
<div><br>
<br>
</div>
</div>
<br>
</blockquote>
And without Concepts?<br>
<br>
In addition to N4428, do we want that the reflection library request
the compiler to generate these tuple-like access?<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------030704070707040309010206--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 29 Dec 2015 06:09:05 -0800 (PST)
Raw View
------=_Part_1814_812868101.1451398146024
Content-Type: multipart/alternative;
boundary="----=_Part_1815_918493657.1451398146025"
------=_Part_1815_918493657.1451398146025
Content-Type: text/plain; charset=UTF-8
FYI: P0144 <http://wg21.link/P0144> already needs to come up with an
extensible mechanism to make an arbitrary user-defined type appear
"tuple-like". So they'll likely have a syntax that provides an extensible
way to make accessing something "tuple-like".
Of course, structured binding syntax can be applied to aggregates without
needing reflection to expose this syntax. But by applying reflection to
their proposed syntax, you would be able to access such objects via
"tuple-like" syntax.
Of course, it probably won't be `tuple_size` and `tuple_element`
specifically. But my point is that we shouldn't duplicate work.
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1815_918493657.1451398146025
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">FYI: <a href=3D"http://wg21.link/P0144">P0144</a> already =
needs to come up with an extensible mechanism to make an arbitrary user-def=
ined type appear "tuple-like". So they'll likely have a synta=
x that provides an extensible way to make accessing something "tuple-l=
ike".<br><br>Of course, structured binding syntax can be applied to ag=
gregates without needing reflection to expose this syntax. But by applying =
reflection to their proposed syntax, you would be able to access such objec=
ts via "tuple-like" syntax.<br><br>Of course, it probably won'=
;t be `tuple_size` and `tuple_element` specifically. But my point is that w=
e shouldn't duplicate work.<br></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1815_918493657.1451398146025--
------=_Part_1814_812868101.1451398146024--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 29 Dec 2015 12:31:28 -0500
Raw View
On 2015-12-29 09:09, Nicol Bolas wrote:
> FYI: P0144 <http://wg21.link/P0144> already needs to come up with an
> extensible mechanism to make an arbitrary user-defined type appear
> "tuple-like".
Something wrong with std::get? I could've sworn I've already several
times encouraged that "tuple-like" should mean "can be used as an
argument to std::get<0>".
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Wed, 30 Dec 2015 08:09:54 +0100
Raw View
--047d7ba972229a60ac05281839e6
Content-Type: text/plain; charset=UTF-8
On Tue, Dec 29, 2015 at 6:31 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:
> On 2015-12-29 09:09, Nicol Bolas wrote:
> > FYI: P0144 <http://wg21.link/P0144> already needs to come up with an
> > extensible mechanism to make an arbitrary user-defined type appear
> > "tuple-like".
>
> Something wrong with std::get? I could've sworn I've already several
> times encouraged that "tuple-like" should mean "can be used as an
> argument to std::get<0>".
>
I haven't heard any strong objections to extending std::get to provide the
decomposition, but it needs further study. It would be similar to
providing your own std::hash specialization. By providing a std::get
specialization for your class type you enable and specify how your type is
decomposed in a tuple-like fashion. Additionally, you would also need a
way to specify how many elements your decomposition contains (maybe an
accompanying std::size template for example).
For some subset of class types (possibly aggregates for example) we imagine
this would be provided automatically.
As for using std::class_traits<C>::class_members to implement this, it is
entirely possible. Keep in mind though that only non-static data members
are desired for this particular use case, and so member functions and
static members would need to be filtered out of
std::class_traits<C>::class_members, which can be done with an appropriate
type predicate (pointer-to-member and non-function).
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7ba972229a60ac05281839e6
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 T=
ue, Dec 29, 2015 at 6:31 PM, Matthew Woehlke <span dir=3D"ltr"><<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,=
204);border-left-style:solid;padding-left:1ex">On 2015-12-29 09:09, Nicol B=
olas wrote:<br>
> FYI: P0144 <<a href=3D"http://wg21.link/P0144" rel=3D"noreferrer" t=
arget=3D"_blank">http://wg21.link/P0144</a>> already needs to come up wi=
th an<br>
<span class=3D"">> extensible mechanism to make an arbitrary user-define=
d type appear<br>
> "tuple-like".<br>
<br>
</span>Something wrong with std::get? I could've sworn I've already=
several<br>
times encouraged that "tuple-like" should mean "can be used =
as an<br>
argument to std::get<0>".<br></blockquote><div><br></div><div>I =
haven't heard any strong objections to extending std::get to provide th=
e decomposition, but it needs further study.=C2=A0 It would be similar to p=
roviding your own std::hash specialization.=C2=A0 By providing a std::get s=
pecialization for your class type you enable and specify how your type is d=
ecomposed in a tuple-like fashion.=C2=A0 Additionally, you would also need =
a way to specify how many elements your decomposition contains (maybe an ac=
companying std::size template for example).</div><div><br></div><div>For so=
me subset of class types (possibly aggregates for example) we imagine this =
would be provided automatically.</div><div><br></div><div>As for using=C2=
=A0std::class_traits<C>::class_members to implement this, it is entir=
ely possible.=C2=A0 Keep in mind though that only non-static data members a=
re desired for this particular use case, and so member functions and static=
members would need to be filtered out of std::class_traits<C>::class=
_members, which can be done with an appropriate type predicate (pointer-to-=
member and non-function).</div></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7ba972229a60ac05281839e6--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 30 Dec 2015 10:37:45 +0100
Raw View
This is a multi-part message in MIME format.
--------------010201010603030204080209
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 29/12/2015 15:09, Nicol Bolas a =C3=A9crit :
> FYI: P0144 <http://wg21.link/P0144> already needs to come up with an=20
> extensible mechanism to make an arbitrary user-defined type appear=20
> "tuple-like". So they'll likely have a syntax that provides an=20
> extensible way to make accessing something "tuple-like".
>
To which extension mechanisms are you referring to?
> Of course, structured binding syntax can be applied to aggregates=20
> without needing reflection to expose this syntax. But by applying=20
> reflection to their proposed syntax, you would be able to access such=20
> objects via "tuple-like" syntax.
>
> Of course, it probably won't be `tuple_size` and `tuple_element`=20
> specifically. But my point is that we shouldn't duplicate work.
>
Could you elaborate?
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------010201010603030204080209
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 29/12/2015 15:09, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:43daa6cd-e152-43c1-ab51-0661779d344b@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">FYI: <a moz-do-not-send=3D"true"
href=3D"http://wg21.link/P0144">P0144</a> already needs to come
up with an extensible mechanism to make an arbitrary
user-defined type appear "tuple-like". So they'll likely have a
syntax that provides an extensible way to make accessing
something "tuple-like".<br>
<br>
</div>
</blockquote>
To which extension mechanisms are you referring to?<br>
<blockquote
cite=3D"mid:43daa6cd-e152-43c1-ab51-0661779d344b@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">Of course, structured binding syntax can be applied
to aggregates without needing reflection to expose this syntax.
But by applying reflection to their proposed syntax, you would
be able to access such objects via "tuple-like" syntax.<br>
<br>
Of course, it probably won't be `tuple_size` and `tuple_element`
specifically. But my point is that we shouldn't duplicate work.<br>
</div>
<br>
</blockquote>
Could you elaborate?<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------010201010603030204080209--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 30 Dec 2015 10:45:33 -0500
Raw View
On 2015-12-30 02:09, Andrew Tomazos wrote:
> On Tue, Dec 29, 2015 at 6:31 PM, Matthew Woehlke wrote:
>> On 2015-12-29 09:09, Nicol Bolas wrote:
>>> FYI: P0144 <http://wg21.link/P0144> already needs to come up with an
>>> extensible mechanism to make an arbitrary user-defined type appear
>>> "tuple-like".
>>
>> Something wrong with std::get? I could've sworn I've already several
>> times encouraged that "tuple-like" should mean "can be used as an
>> argument to std::get<0>".
>=20
> I haven't heard any strong objections to extending std::get to provide th=
e
> decomposition, but it needs further study.
Are you talking about decomposing *aggregates*, or decomposing other
things? The above is meant only to refer to the "extensible mechanism to
make an arbitrary user-defined type appear 'tuple-like'". The point I
was intending to make is that, to me, it seems obvious that providing an
implementation of 'get<0>'=C2=B9=C2=B2 should be that mechanism.
(=C2=B9 Which, sorry, should possibly be found by ADL rather than being
required to be in namespace std, similar to how begin()/end() are used.)
(=C2=B2 ...and, as relevant, get<1>, get<2>, etc.)
> It would be similar to providing your own std::hash specialization.
> By providing a std::get specialization for your class type you enable
> and specify how your type is decomposed in a tuple-like fashion.
Yes, exactly :-).
> Additionally, you would also need a way to specify how many elements
> your decomposition contains (maybe an accompanying std::size template
> for example).
Are you sure? I was under the impression that the size is determined by
how large you can make N (of 'get<N>') before no such definition can be
formed. (Certainly for the purposes of P0144, I'd believed this to be
the case. Maybe for tuple-like an explicit size query is needed, though
even there I wonder if there can't be a generic implementation that
derives the result in the aforementioned manner. Especially if it
leverages a compiler built-in to do so.)
> For some subset of class types (possibly aggregates for example) we imagi=
ne
> this would be provided automatically.
Sure; that's not a problem. It's being able to extend "tuple-like" to
arbitrary types (that wouldn't be covered by this generic case) that
interests me. (I'll also note that this includes types from external
libraries. I think this is important to users being able to extend these
new features to libraries that "haven't caught up yet". As for the
counter-argument, that maybe the library wants to forbid it, presumably
this can be accomplished by providing get<0> as explicitly deleted.)
> As for using std::class_traits<C>::class_members to implement this, it is
> entirely possible. Keep in mind though that only non-static data members
> are desired for this particular use case, and so member functions and
> static members would need to be filtered out of
> std::class_traits<C>::class_members, which can be done with an appropriat=
e
> type predicate (pointer-to-member and non-function).
If we can make the generic case work with an appropriate generic
implementation of get<N>, that's certainly a bonus :-).
--=20
Matthew
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 30 Dec 2015 10:47:48 -0500
Raw View
On 2015-12-30 04:37, Vicente J. Botet Escriba wrote:
> Le 29/12/2015 15:09, Nicol Bolas a =C3=A9crit :
>> FYI: P0144 <http://wg21.link/P0144> already needs to come up with an
>> extensible mechanism to make an arbitrary user-defined type appear
>> "tuple-like". So they'll likely have a syntax that provides an
>> extensible way to make accessing something "tuple-like".
>
> To which extension mechanisms are you referring to?
We don't know (yet). That was the point. Specifically, that both
proposals need such a mechanism, and that it is clearly beneficial that
they use the same one.
>> Of course, it probably won't be `tuple_size` and `tuple_element`
>> specifically. But my point is that we shouldn't duplicate work.
>
> Could you elaborate?
See above? See also my other posts in this thread.
--=20
Matthew
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 3 Jan 2016 16:47:53 +0100
Raw View
Le 30/12/2015 16:45, Matthew Woehlke a =C3=A9crit :
> On 2015-12-30 02:09, Andrew Tomazos wrote:
>> On Tue, Dec 29, 2015 at 6:31 PM, Matthew Woehlke wrote:
>>> On 2015-12-29 09:09, Nicol Bolas wrote:
>>>> FYI: P0144 <http://wg21.link/P0144> already needs to come up with an
>>>> extensible mechanism to make an arbitrary user-defined type appear
>>>> "tuple-like".
>>> Something wrong with std::get? I could've sworn I've already several
>>> times encouraged that "tuple-like" should mean "can be used as an
>>> argument to std::get<0>".
>> I haven't heard any strong objections to extending std::get to provide t=
he
>> decomposition, but it needs further study.
> Are you talking about decomposing *aggregates*, or decomposing other
> things? The above is meant only to refer to the "extensible mechanism to
> make an arbitrary user-defined type appear 'tuple-like'". The point I
> was intending to make is that, to me, it seems obvious that providing an
> implementation of 'get<0>'=C2=B9=C2=B2 should be that mechanism.
>
> (=C2=B9 Which, sorry, should possibly be found by ADL rather than being
> required to be in namespace std, similar to how begin()/end() are used.)
>
> (=C2=B2 ...and, as relevant, get<1>, get<2>, etc.)
My concern is that the compiler know already an aggregate could be seen=20
as a tuple-like type. So requesting the user to do the mapping is=20
cumbersome. Remember how many macros (Boost.Fusion) have been defined to=20
make this kid of mapping explicit.
>> It would be similar to providing your own std::hash specialization.
>> By providing a std::get specialization for your class type you enable
>> and specify how your type is decomposed in a tuple-like fashion.
> Yes, exactly :-).
I agree. But why the get function must be provided by the user. Why not=20
by the compiler if needed.
I would also like the compiler to be able to generate the hash_value, as=20
well as the swap implementations and many more as proposed in N4475 for=20
Default comparisons.
>
>> Additionally, you would also need a way to specify how many elements
>> your decomposition contains (maybe an accompanying std::size template
>> for example).
> Are you sure? I was under the impression that the size is determined by
> how large you can make N (of 'get<N>') before no such definition can be
> formed. (Certainly for the purposes of P0144, I'd believed this to be
> the case. Maybe for tuple-like an explicit size query is needed, though
> even there I wonder if there can't be a generic implementation that
> derives the result in the aforementioned manner. Especially if it
> leverages a compiler built-in to do so.)
>
>> For some subset of class types (possibly aggregates for example) we imag=
ine
>> this would be provided automatically.
> Sure; that's not a problem. It's being able to extend "tuple-like" to
> arbitrary types (that wouldn't be covered by this generic case) that
> interests me. (I'll also note that this includes types from external
> libraries. I think this is important to users being able to extend these
> new features to libraries that "haven't caught up yet". As for the
> counter-argument, that maybe the library wants to forbid it, presumably
> this can be accomplished by providing get<0> as explicitly deleted.)
I think that we all agree that if something is generated by default, we=20
need a mechanism to inhibit the generation. For function =3D delete seems=
=20
the adopted way. For traits, I believe that the user could inhibit them=20
by defining them as empty
template<>
struct tuple_size<MyType> {};
template<int N>
struct tuple_element<N, MyType> {};
template<int N>
auto get(MyType&) =3D delete;
>
>> As for using std::class_traits<C>::class_members to implement this, it i=
s
>> entirely possible. Keep in mind though that only non-static data member=
s
>> are desired for this particular use case, and so member functions and
>> static members would need to be filtered out of
>> std::class_traits<C>::class_members, which can be done with an appropria=
te
>> type predicate (pointer-to-member and non-function).
Yes, of course.
> If we can make the generic case work with an appropriate generic
> implementation of get<N>, that's certainly a bonus :-).
>
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 04 Jan 2016 10:56:19 -0500
Raw View
On 2016-01-03 10:47, Vicente J. Botet Escriba wrote:
> My concern is that the compiler know already an aggregate could be seen
> as a tuple-like type. So requesting the user to do the mapping is
> cumbersome.
Agreed. I tend to think that should still be get<N>, but that the
compiler and/or standard library should somehow arrange to provide an
implementation of that for aggregates for which a specialized
implementation does not already exist. (Being explicitly deleted counts
as "existing", here. Presumably the "default" version is a generic
template, so existing rules of specialization are all that is needed for
overrides to DTRT.)
>> [...providing get<N> for user types...]
> I agree. But why the get function must be provided by the user. Why not
> by the compiler if needed.
I am talking specifically about *non*-aggregate types, e.g. QPoint,
Eigen::Vector3d, etc. For *aggregates*, I agree that it's desirable that
an implementation be available "by default".
> I think that we all agree that if something is generated by default, we
> need a mechanism to inhibit the generation. For function = delete seems
> the adopted way. For traits, I believe that the user could inhibit them
> by defining them as empty
>
> template<>
> struct tuple_size<MyType> {};
> template<int N>
> struct tuple_element<N, MyType> {};
> template<int N>
> auto get(MyType&) = delete;
If "tuple-like" is defined as "get<0> works", providing a deleted
specialization of get<0> (third part of the above) should be sufficient;
the first two should be superfluous.
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 5 Jan 2016 01:26:09 +0100
Raw View
This is a multi-part message in MIME format.
--------------080908000307050606000403
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 04/01/2016 16:56, Matthew Woehlke a =C3=A9crit :
> On 2016-01-03 10:47, Vicente J. Botet Escriba wrote:
>> My concern is that the compiler know already an aggregate could be seen
>> as a tuple-like type. So requesting the user to do the mapping is
>> cumbersome.
> Agreed. I tend to think that should still be get<N>, but that the
> compiler and/or standard library should somehow arrange to provide an
> implementation of that for aggregates for which a specialized
> implementation does not already exist. (Being explicitly deleted counts
> as "existing", here. Presumably the "default" version is a generic
> template, so existing rules of specialization are all that is needed for
> overrides to DTRT.)
>
>>> [...providing get<N> for user types...]
>> I agree. But why the get function must be provided by the user. Why not
>> by the compiler if needed.
> I am talking specifically about *non*-aggregate types, e.g. QPoint,
> Eigen::Vector3d, etc.
Agreed. Adding the tuple-like for these non-aggregated classes should be=20
done by the user.
> For *aggregates*, I agree that it's desirable that
> an implementation be available "by default".
BTW, how can I check if a class is an aggregate?
* array type
* class type (typically, struct or union), that has
* (1) no private or protected non-static data members
* (2) no user-provided constructors (explicitly defaulted or
deleted constructors are allowed) (since C++11)
* (3) no base classes
* (4) no virtual member functions
With reflection n4428 API I don't see how to check for (4). (2) would=20
need some specific treatment for (explicitly defaulted or deleted=20
constructors are allowed) and a constructor list.
I'm wondering if a type trait is_aggregate is not missing.
I believe we agree that the tuple-like interface should be generated for=20
aggregates that are not array nor union.
>> I think that we all agree that if something is generated by default, we
>> need a mechanism to inhibit the generation. For function =3D delete seem=
s
>> the adopted way. For traits, I believe that the user could inhibit them
>> by defining them as empty
>>
>> template<>
>> struct tuple_size<MyType> {};
>> template<int N>
>> struct tuple_element<N, MyType> {};
>> template<int N>
>> auto get(MyType&) =3D delete;
> If "tuple-like" is defined as "get<0> works", providing a deleted
> specialization of get<0> (third part of the above) should be sufficient;
> the first two should be superfluous.
>
Maybe you are right, but having tuple_size::value/tuple_element::type=20
defined and not having get<N> seems to me risky and incoherent.
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------080908000307050606000403
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 04/01/2016 16:56, Matthew Woehlke a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:n6e4n4$q68$1@ger.gmane.org" type=3D"cite">
<pre wrap=3D"">On 2016-01-03 10:47, Vicente J. Botet Escriba wrote:
</pre>
<blockquote type=3D"cite">
<pre wrap=3D"">My concern is that the compiler know already an aggr=
egate could be seen
as a tuple-like type. So requesting the user to do the mapping is
cumbersome.
</pre>
</blockquote>
<pre wrap=3D"">
Agreed. I tend to think that should still be get<N>, but that the
compiler and/or standard library should somehow arrange to provide an
implementation of that for aggregates for which a specialized
implementation does not already exist. (Being explicitly deleted counts
as "existing", here. Presumably the "default" version is a generic
template, so existing rules of specialization are all that is needed for
overrides to DTRT.)
</pre>
<blockquote type=3D"cite">
<blockquote type=3D"cite">
<pre wrap=3D"">[...providing get<N> for user types...]
</pre>
</blockquote>
<pre wrap=3D"">I agree. But why the get function must be provided b=
y the user. Why not
by the compiler if needed.
</pre>
</blockquote>
<pre wrap=3D"">
I am talking specifically about *non*-aggregate types, e.g. QPoint,
Eigen::Vector3d, etc. </pre>
</blockquote>
Agreed. Adding the tuple-like for these non-aggregated classes
should be done by the user.<br>
<blockquote cite=3D"mid:n6e4n4$q68$1@ger.gmane.org" type=3D"cite">
<pre wrap=3D"">For *aggregates*, I agree that it's desirable that
an implementation be available "by default".
</pre>
</blockquote>
BTW, how can I check if a class is an aggregate?<br>
<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
<ul>
<li> array type
</li>
<li> class type (typically, <span class=3D"t-c"><span
class=3D"mw-geshi cpp source-cpp"><span class=3D"kw1">struct</s=
pan></span></span>
or <span class=3D"t-c"><span class=3D"mw-geshi cpp source-cpp"><spa=
n
class=3D"kw1">union</span></span></span>), that has
</li>
</ul>
<dl>
<dd>
<ul>
<li>(1) no private or protected non-static data members
</li>
<li> (2) no user-provided constructors <span class=3D"t-rev-inl
t-since-cxx11"><span>(explicitly defaulted or deleted
constructors are allowed)</span> <span><span
class=3D"t-mark-rev t-since-cxx11">(since C++11)</span></=
span></span>
</li>
<li> (3) no base classes
</li>
<li> (4) no virtual member functions
</li>
</ul>
</dd>
</dl>
<br>
With reflection n4428 API I don't see how to check for (4). (2)
would need some specific treatment for <span class=3D"t-rev-inl
t-since-cxx11"><span>(explicitly defaulted or deleted constructors
are allowed) and a constructor list.</span></span><br>
<br>
I'm wondering if a type trait is_aggregate is not missing.<br>
<br>
I believe we agree that the tuple-like interface should be generated
for aggregates that are not array nor union.<br>
<blockquote cite=3D"mid:n6e4n4$q68$1@ger.gmane.org" type=3D"cite">
<pre wrap=3D"">
</pre>
<blockquote type=3D"cite">
<pre wrap=3D"">I think that we all agree that if something is gener=
ated by default, we
need a mechanism to inhibit the generation. For function =3D delete seems
the adopted way. For traits, I believe that the user could inhibit them
by defining them as empty
template<>
struct tuple_size<MyType> {};
template<int N>
struct tuple_element<N, MyType> {};
template<int N>
auto get(MyType&) =3D delete;
</pre>
</blockquote>
<pre wrap=3D"">
If "tuple-like" is defined as "get<0> works", providing a deleted
specialization of get<0> (third part of the above) should be sufficie=
nt;
the first two should be superfluous.
</pre>
</blockquote>
<font size=3D"+1">Maybe you are right, but having
tuple_size::value/tuple_element::type defined</font> and not
having get<N> seems to me risky and incoherent.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------080908000307050606000403--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 4 Jan 2016 18:52:50 -0800 (PST)
Raw View
------=_Part_6967_858280329.1451962370164
Content-Type: multipart/alternative;
boundary="----=_Part_6968_1834866551.1451962370164"
------=_Part_6968_1834866551.1451962370164
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, January 4, 2016 at 7:26:12 PM UTC-5, Vicente J. Botet Escriba=20
wrote:
>
> Le 04/01/2016 16:56, Matthew Woehlke a =C3=A9crit :
>
> On 2016-01-03 10:47, Vicente J. Botet Escriba wrote:
>
> My concern is that the compiler know already an aggregate could be seen
> as a tuple-like type. So requesting the user to do the mapping is
> cumbersome.
>
> Agreed. I tend to think that should still be get<N>, but that the
> compiler and/or standard library should somehow arrange to provide an
> implementation of that for aggregates for which a specialized
> implementation does not already exist. (Being explicitly deleted counts
> as "existing", here. Presumably the "default" version is a generic
> template, so existing rules of specialization are all that is needed for
> overrides to DTRT.)
>
>
> [...providing get<N> for user types...]
>
> I agree. But why the get function must be provided by the user. Why not
> by the compiler if needed.
>
> I am talking specifically about *non*-aggregate types, e.g. QPoint,
> Eigen::Vector3d, etc.=20
>
> Agreed. Adding the tuple-like for these non-aggregated classes should be=
=20
> done by the user.
>
> For *aggregates*, I agree that it's desirable that
> an implementation be available "by default".
>
> BTW, how can I check if a class is an aggregate?
>
>
> - array type=20
> - class type (typically, struct or union), that has=20
>
>
> - (1) no private or protected non-static data members=20
> - (2) no user-provided constructors (explicitly defaulted or deleted=
=20
> constructors are allowed) (since C++11)=20
> - (3) no base classes=20
> - (4) no virtual member functions=20
>
>
> With reflection n4428 API I don't see how to check for (4). (2) would nee=
d=20
> some specific treatment for (explicitly defaulted or deleted constructors=
=20
> are allowed) and a constructor list.
>
> I'm wondering if a type trait is_aggregate is not missing.
>
Does it matter?
The notion of "aggregate" really only matters for initialization:=20
aggregates undergo aggregate initialization. You're not actually trying to=
=20
initialize something; you're just creating tuple-style accessors for them.
So why limit it specifically to non-virtual types? And what's the point of=
=20
the constructor limitation? The only limitation you absolutely need for=20
this automated system is having all NSDMs be public.
Plus, C++17 is expanding the definition of aggregate to include types that=
=20
have aggregate base classes.
The way I see it, you should define the limitations that are most=20
reasonable for your feature, and give such types a name. Member-enumerable,=
=20
or public-accessible or something. Whether all such types are aggregates or=
=20
not is irrelevant.
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_6968_1834866551.1451962370164
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, January 4, 2016 at 7:26:12 PM UTC-5, Vicente J. Botet Escriba wr=
ote:<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 04/01/2016 16:56, Matthew Woehlke a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">
<pre>On 2016-01-03 10:47, Vicente J. Botet Escriba wrote:
</pre>
<blockquote type=3D"cite">
<pre>My concern is that the compiler know already an aggregate coul=
d be seen
as a tuple-like type. So requesting the user to do the mapping is
cumbersome.
</pre>
</blockquote>
<pre>Agreed. I tend to think that should still be get<N>, but t=
hat the
compiler and/or standard library should somehow arrange to provide an
implementation of that for aggregates for which a specialized
implementation does not already exist. (Being explicitly deleted counts
as "existing", here. Presumably the "default" version i=
s a generic
template, so existing rules of specialization are all that is needed for
overrides to DTRT.)
</pre>
<blockquote type=3D"cite">
<blockquote type=3D"cite">
<pre>[...providing get<N> for user types...]
</pre>
</blockquote>
<pre>I agree. But why the get function must be provided by the user=
.. Why not
by the compiler if needed.
</pre>
</blockquote>
<pre>I am talking specifically about *non*-aggregate types, e.g. QPoi=
nt,
Eigen::Vector3d, etc. </pre>
</blockquote>
Agreed. Adding the tuple-like for these non-aggregated classes
should be done by the user.<br>
<blockquote type=3D"cite">
<pre>For *aggregates*, I agree that it's desirable that
an implementation be available "by default".
</pre>
</blockquote>
BTW, how can I check if a class is an aggregate?<br>
<br>
=20
<ul>
<li> array type
</li>
<li> class type (typically, <span><span><span>struct</span></span></s=
pan>
or <span><span><span>union</span></span></span>), that has
</li>
</ul>
<dl>
<dd>
<ul>
<li>(1) no private or protected non-static data members
</li>
<li> (2) no user-provided constructors <span><span>(explicitly de=
faulted or deleted
constructors are allowed)</span> <span><span>(since C++11)<=
/span></span></span>
</li>
<li> (3) no base classes
</li>
<li> (4) no virtual member functions
</li>
</ul>
</dd>
</dl>
<br>
With reflection n4428 API I don't see how to check for (4). (2)
would need some specific treatment for <span><span>(explicitly defaulte=
d or deleted constructors
are allowed) and a constructor list.</span></span><br>
<br>
I'm wondering if a type trait is_aggregate is not missing.<br></div=
></blockquote><div><br>Does it matter?<br><br>The notion of "aggregate=
" really only matters for initialization: aggregates undergo aggregate=
initialization. You're not actually trying to initialize something; yo=
u're just creating tuple-style accessors for them.<br><br>So why limit =
it specifically to non-virtual types? And what's the point of the const=
ructor limitation? The only limitation you absolutely need for this automat=
ed system is having all NSDMs be public.<br><br>Plus, C++17 is expanding th=
e definition of aggregate to include types that have aggregate base classes=
..<br><br>The way I see it, you should define the limitations that are most =
reasonable for your feature, and give such types a name. Member-enumerable,=
or public-accessible or something. Whether all such types are aggregates o=
r not is irrelevant.<br></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_6968_1834866551.1451962370164--
------=_Part_6967_858280329.1451962370164--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 5 Jan 2016 05:08:39 +0200
Raw View
On 5 January 2016 at 02:26, Vicente J. Botet Escriba
<vicente.botet@wanadoo.fr> wrote:
> BTW, how can I check if a class is an aggregate?
> array type
> class type (typically, struct or union), that has
> (1) no private or protected non-static data members
> (2) no user-provided constructors (explicitly defaulted or deleted
> constructors are allowed) (since C++11)
> (3) no base classes
> (4) no virtual member functions
> With reflection n4428 API I don't see how to check for (4). (2) would need
is_polymorphic can check for it. The question is why would you check
for an aggregate?
> I'm wondering if a type trait is_aggregate is not missing.
What would you do with such a trait? If you don't want a
destructuring-bind to be
generated for your type, you would presumably disable the generation
of a destructuring-bind
for your type. Where does an is_aggregate trait enter the picture?
It's easy to want all sorts of "give be a bool indicating whether this
type has such-and-such
fine-grained core language properties". There are downsides to it, and
there's been a lot
of talk in the committee about how such traits and the proliferation
of such traits
must be avoided, mostly because they often don't provide a useful answer to
a reasonable question. is_trivial is one of the glaring examples of
that. is_final
as specified is another, because it will not tell you whether you can
derive from
a type, it just tells you whether the type was declared final.
is_abstract is similar,
it will not answer the more general question "can I create objects of
this type?".
So, that sort of traits are unlikely to be what you need, and adding
more such traits
does little more than harm.
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 05 Jan 2016 10:28:59 -0500
Raw View
On 2016-01-04 21:52, Nicol Bolas wrote:
> On Monday, January 4, 2016 at 7:26:12 PM UTC-5, Vicente J. Botet Escriba
> wrote:
>> BTW, how can I check if a class is an aggregate?
>>
>> - array type
>> - class type (typically, struct or union), that has
I realize you are copying from the definition of aggregate, but I'll
note that a union is probably not tuple-like :-). They can only have one
active member, and the compiler can't generate code to know which member
is active. Therefore, I don't see how you could implement the
get-element (get<N> or whatever) function for a union.
>> - (1) no private or protected non-static data members
>> - (2) no user-provided constructors (explicitly defaulted or deleted
>> constructors are allowed) (since C++11)
>> - (3) no base classes
>> - (4) no virtual member functions
>>
>> I'm wondering if a type trait is_aggregate is not missing.
>
> Does it matter?
>
> The notion of "aggregate" really only matters for initialization:
> aggregates undergo aggregate initialization. You're not actually trying to
> initialize something; you're just creating tuple-style accessors for them.
>
> So why limit it specifically to non-virtual types?
Agreed this may not be necessary.
> And what's the point of the constructor limitation?
None. Note however that C++14 already removes this restriction; I
presume Vicente including it was accident/oversight.
> The only limitation you absolutely need for
> this automated system is having all NSDMs be public.
Right.
> Plus, C++17 is expanding the definition of aggregate to include types that
> have aggregate base classes.
Sure, and this makes sense for "tuple-like" also.
> The way I see it, you should define the limitations that are most
> reasonable for your feature, and give such types a name. Member-enumerable,
> or public-accessible or something. Whether all such types are aggregates or
> not is irrelevant.
In fairness, I am probably partly at fault here. I have been using
"aggregate" because that most closely matches the reasonable
requirements. There may well be something of a disconnect between what
should qualify for implicitly tuple-like and the standardese definition
of "aggregate". (If there is a better term, please let me know; thanks!)
So, the relevant question becomes, how do we determine if a complex type
has no non-public NSDM's (without reflection)?
On 2016-01-04 22:08, Ville Voutilainen wrote:
> The question is why would you check for an aggregate?
The goal is that get<N> would be implicitly defined for any "aggregate".
It should *not* be defined however for types that have non-public
NSDM's. The question is how to achieve this.
I should note that one answer is "compiler magic". If a standard trait
is going to be a problem, that may be a strong argument to use compiler
magic rather than a portable library solution.
>> Maybe you are right, but having tuple_size::value/tuple_element::type
>> defined and not having get<N> seems to me risky and incoherent.
*Are* they "defined"? The generic implementation of these should require
that get<0>(tuple_like) is well formed. If no get<0> exists, the generic
versions of tuple_size/tuple_element would not be well formed, with no
need to explicitly specialize them.
I could be wrong, though :-).
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 5 Jan 2016 08:00:53 -0800 (PST)
Raw View
------=_Part_2953_2025593443.1452009654093
Content-Type: multipart/alternative;
boundary="----=_Part_2954_544723141.1452009654094"
------=_Part_2954_544723141.1452009654094
Content-Type: text/plain; charset=UTF-8
On Tuesday, January 5, 2016 at 10:29:17 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-04 21:52, Nicol Bolas wrote:
> > On Monday, January 4, 2016 at 7:26:12 PM UTC-5, Vicente J. Botet Escriba
> > wrote:
> >> BTW, how can I check if a class is an aggregate?
> >>
> >> - array type
> >> - class type (typically, struct or union), that has
>
> I realize you are copying from the definition of aggregate, but I'll
> note that a union is probably not tuple-like :-). They can only have one
> active member, and the compiler can't generate code to know which member
> is active. Therefore, I don't see how you could implement the
> get-element (get<N> or whatever) function for a union.
>
> >> - (1) no private or protected non-static data members
> >> - (2) no user-provided constructors (explicitly defaulted or deleted
> >> constructors are allowed) (since C++11)
> >> - (3) no base classes
> >> - (4) no virtual member functions
> >>
> >> I'm wondering if a type trait is_aggregate is not missing.
> >
> > Does it matter?
> >
> > The notion of "aggregate" really only matters for initialization:
> > aggregates undergo aggregate initialization. You're not actually trying
> to
> > initialize something; you're just creating tuple-style accessors for
> them.
> >
> > So why limit it specifically to non-virtual types?
>
> Agreed this may not be necessary.
>
> > And what's the point of the constructor limitation?
>
> None. Note however that C++14 already removes this restriction; I
> presume Vicente including it was accident/oversight.
>
No it doesn't. From N4567, 8.5.1, p1:
An aggregate is an array or a class (Clause 9) with no user-provided
> constructors...
>
What C++14 changed was the idea of default member initializers implicitly
providing a default constructor (to fill in the defaults). By removing
that, it made it possible for classes with DMIs to be aggregates.
Even C++17 is not going to allow aggregates to have user-provided
constructors. Remember: the type category "aggregate" exists *solely* to
say when aggregate initialization can happen; nothing more. If you provided
a constructor, you don't want aggregate initialization; you want
constructor initialization. Providing a constructor is you saying, "this
type must be built using one of these functions".
On 2016-01-04 22:08, Ville Voutilainen wrote:
> > The question is why would you check for an aggregate?
>
> The goal is that get<N> would be implicitly defined for any "aggregate".
> It should *not* be defined however for types that have non-public
> NSDM's. The question is how to achieve this.
>
> I should note that one answer is "compiler magic". If a standard trait
> is going to be a problem, that may be a strong argument to use compiler
> magic rather than a portable library solution.
>
Well, reflection of any kind, which this whole idea relies on, is going to
require compiler magic. Presumably, the reflection API has a way to say if
an NSDM is not public, so the reflection metaprogramming should simply
`static_assert` on 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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2954_544723141.1452009654094
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Tuesday, January 5, 2016 at 10:29:17 AM UTC-5, Matthew Woehlke w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-04 21:52, Nico=
l Bolas wrote:
<br>> On Monday, January 4, 2016 at 7:26:12 PM UTC-5, Vicente J. Botet E=
scriba=20
<br>> wrote:
<br>>> BTW, how can I check if a class is an aggregate?
<br>>>
<br>>> =C2=A0 =C2=A0- array type=20
<br>>> =C2=A0 =C2=A0- class type (typically, struct or union), that h=
as=20
<br>
<br>I realize you are copying from the definition of aggregate, but I'l=
l
<br>note that a union is probably not tuple-like :-). They can only have on=
e
<br>active member, and the compiler can't generate code to know which m=
ember
<br>is active. Therefore, I don't see how you could implement the
<br>get-element (get<N> or whatever) function for a union.
<br>
<br>>> =C2=A0 =C2=A0- (1) no private or protected non-static data mem=
bers=20
<br>>> =C2=A0 =C2=A0- (2) no user-provided constructors (explicitly d=
efaulted or deleted=20
<br>>> =C2=A0 =C2=A0constructors are allowed) (since C++11)=20
<br>>> =C2=A0 =C2=A0- (3) no base classes=20
<br>>> =C2=A0 =C2=A0- (4) no virtual member functions=20
<br>>>
<br>>> I'm wondering if a type trait is_aggregate is not missing.
<br>>=20
<br>> Does it matter?
<br>>=20
<br>> The notion of "aggregate" really only matters for initia=
lization:=20
<br>> aggregates undergo aggregate initialization. You're not actual=
ly trying to=20
<br>> initialize something; you're just creating tuple-style accesso=
rs for them.
<br>>=20
<br>> So why limit it specifically to non-virtual types?
<br>
<br>Agreed this may not be necessary.
<br>
<br>> And what's the point of the constructor limitation?
<br>
<br>None. Note however that C++14 already removes this restriction; I
<br>presume Vicente including it was accident/oversight.<br></blockquote><d=
iv><br>No it doesn't. From N4567, 8.5.1, p1:<br><br><blockquote style=
=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); p=
adding-left: 1ex;" class=3D"gmail_quote">An aggregate is an array or a clas=
s (Clause 9) with no user-provided constructors...<br></blockquote><div><br=
>What C++14 changed was the idea of default member initializers implicitly =
providing a default constructor (to fill in the defaults). By removing that=
, it made it possible for classes with DMIs to be aggregates.<br><br>Even C=
++17 is not going to allow aggregates to have user-provided constructors. R=
emember: the type category "aggregate" exists <i>solely</i> to sa=
y when aggregate initialization can happen; nothing more. If you provided a=
constructor, you don't want aggregate initialization; you want constru=
ctor initialization. Providing a constructor is you saying, "this type=
must be built using one of these functions".<br><br></div></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">
On 2016-01-04 22:08, Ville Voutilainen wrote:
<br>> The question is why would you check for an aggregate?
<br>
<br>The goal is that get<N> would be implicitly defined for any "=
;aggregate".
<br>It should *not* be defined however for types that have non-public
<br>NSDM's. The question is how to achieve this.
<br>
<br>I should note that one answer is "compiler magic". If a stand=
ard trait
<br>is going to be a problem, that may be a strong argument to use compiler
<br>magic rather than a portable library solution.
<br></blockquote><div><br>Well, reflection of any kind, which this whole id=
ea relies on, is going to require compiler magic. Presumably, the reflectio=
n API has a way to say if an NSDM is not public, so the reflection metaprog=
ramming should simply `static_assert` on that.<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">
</blockquote>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_2954_544723141.1452009654094--
------=_Part_2953_2025593443.1452009654093--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 05 Jan 2016 11:37:59 -0500
Raw View
On 2016-01-05 11:00, Nicol Bolas wrote:
> On Tuesday, January 5, 2016 at 10:29:17 AM UTC-5, Matthew Woehlke wrote:
>> On 2016-01-04 21:52, Nicol Bolas wrote:
>>> And what's the point of the constructor limitation?
>>
>> None. Note however that C++14 already removes this restriction; I
>> presume Vicente including it was accident/oversight.
>
> No it doesn't.
AAACK!! Sorry, I somehow managed to transpose this with "no default
member initializers". Although... it's not entirely clear to me why
those should be different :-).
Well, okay, it is; the ctor can have side-effects. However, per your
point, I am inclined to agree that presence or absence of ctors should
not make a difference for "tuple-like". In *that* context there is not
so much difference between default initialization and a user-provided
default ctor.
> On 2016-01-04 22:08, Ville Voutilainen wrote:
>>> The question is why would you check for an aggregate?
>>
>> The goal is that get<N> would be implicitly defined for any "aggregate".
>> It should *not* be defined however for types that have non-public
>> NSDM's. The question is how to achieve this.
>>
>> I should note that one answer is "compiler magic". If a standard trait
>> is going to be a problem, that may be a strong argument to use compiler
>> magic rather than a portable library solution.
>
> Well, reflection of any kind, which this whole idea relies on, is going to
> require compiler magic.
True. The question could be better expressed as whether the compiler
magic provides get<N> *directly* (as in, there may be no visible
declaration of the generic form of such), or whether get<N> is (visibly,
in the standard library) implemented with the help of traits (which
themselves are compiler magic, but have broader applicability).
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 5 Jan 2016 10:20:18 -0800 (PST)
Raw View
------=_Part_193_1996941231.1452018018351
Content-Type: multipart/alternative;
boundary="----=_Part_194_268878288.1452018018351"
------=_Part_194_268878288.1452018018351
Content-Type: text/plain; charset=UTF-8
On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-05 11:00, Nicol Bolas wrote:
> > On 2016-01-04 22:08, Ville Voutilainen wrote:
> >>> The question is why would you check for an aggregate?
> >>
> >> The goal is that get<N> would be implicitly defined for any
> "aggregate".
> >> It should *not* be defined however for types that have non-public
> >> NSDM's. The question is how to achieve this.
> >>
> >> I should note that one answer is "compiler magic". If a standard trait
> >> is going to be a problem, that may be a strong argument to use compiler
> >> magic rather than a portable library solution.
> >
> > Well, reflection of any kind, which this whole idea relies on, is going
> to
> > require compiler magic.
>
> True. The question could be better expressed as whether the compiler
> magic provides get<N> *directly* (as in, there may be no visible
> declaration of the generic form of such), or whether get<N> is (visibly,
> in the standard library) implemented with the help of traits (which
> themselves are compiler magic, but have broader applicability).
>
I say let the whole thing be compiler magic. It'd probably be faster to
compile that way if the compiler can just use intrinsics or whatever to
enumerate the members of the struct.
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_194_268878288.1452018018351
Content-Type: text/html; charset=UTF-8
On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-05 11:00, Nicol Bolas wrote:
<br>> On 2016-01-04 22:08, Ville Voutilainen wrote:
<br>>>> The question is why would you check for an aggregate?
<br>>>
<br>>> The goal is that get<N> would be implicitly defined for any "aggregate".
<br>>> It should *not* be defined however for types that have non-public
<br>>> NSDM's. The question is how to achieve this.
<br>>>
<br>>> I should note that one answer is "compiler magic". If a standard trait
<br>>> is going to be a problem, that may be a strong argument to use compiler
<br>>> magic rather than a portable library solution.
<br>>
<br>> Well, reflection of any kind, which this whole idea relies on, is going to
<br>> require compiler magic.
<br>
<br>True. The question could be better expressed as whether the compiler
<br>magic provides get<N> *directly* (as in, there may be no visible
<br>declaration of the generic form of such), or whether get<N> is (visibly,
<br>in the standard library) implemented with the help of traits (which
<br>themselves are compiler magic, but have broader applicability).
<br></blockquote><div><br>I say let the whole thing be compiler magic. It'd probably be faster to compile that way if the compiler can just use intrinsics or whatever to enumerate the members of the struct.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="https://groups.google.com/a/isocpp.org/group/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
------=_Part_194_268878288.1452018018351--
------=_Part_193_1996941231.1452018018351--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 5 Jan 2016 23:08:07 +0100
Raw View
This is a multi-part message in MIME format.
--------------070800010509000506090405
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-05 11:00, Nicol Bolas wrote:
> > On 2016-01-04 22:08, Ville Voutilainen wrote:
> >>> The question is why would you check for an aggregate?
> >>
> >> The goal is that get<N> would be implicitly defined for any
> "aggregate".
> >> It should *not* be defined however for types that have non-public
> >> NSDM's. The question is how to achieve this.
> >>
> >> I should note that one answer is "compiler magic". If a
> standard trait
> >> is going to be a problem, that may be a strong argument to use
> compiler
> >> magic rather than a portable library solution.
> >
> > Well, reflection of any kind, which this whole idea relies on,
> is going to
> > require compiler magic.
>
> True. The question could be better expressed as whether the compiler
> magic provides get<N> *directly* (as in, there may be no visible
> declaration of the generic form of such), or whether get<N> is
> (visibly,
> in the standard library) implemented with the help of traits (which
> themselves are compiler magic, but have broader applicability).
>
>
> I say let the whole thing be compiler magic. It'd probably be faster=20
> to compile that way if the compiler can just use intrinsics or=20
> whatever to enumerate the members of the struct.
>
Thanks to all for your help. Could we conclude then that the generation=20
should be done when
- (1) no private or protected non-static data members and
- (2) no base classes
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question.
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------070800010509000506090405
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 05/01/2016 19:20, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:487ea013-6fcb-4d2e-8bc7-8fe96cdbf0a9@isocpp.org"
type=3D"cite">On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5,
Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On
2016-01-05 11:00, Nicol Bolas wrote:
<br>
> On 2016-01-04 22:08, Ville Voutilainen wrote: <br>
>>> The question is why would you check for an
aggregate? <br>
>>
<br>
>> The goal is that get<N> would be implicitly
defined for any "aggregate". <br>
>> It should *not* be defined however for types that have
non-public <br>
>> NSDM's. The question is how to achieve this. <br>
>>
<br>
>> I should note that one answer is "compiler magic". If a
standard trait <br>
>> is going to be a problem, that may be a strong argument
to use compiler <br>
>> magic rather than a portable library solution. <br>
> <br>
> Well, reflection of any kind, which this whole idea relies
on, is going to <br>
> require compiler magic.
<br>
<br>
True. The question could be better expressed as whether the
compiler
<br>
magic provides get<N> *directly* (as in, there may be no
visible
<br>
declaration of the generic form of such), or whether
get<N> is (visibly,
<br>
in the standard library) implemented with the help of traits
(which
<br>
themselves are compiler magic, but have broader applicability).
<br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic. It'd probably be
faster to compile that way if the compiler can just use
intrinsics or whatever to enumerate the members of the struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude then that the
generation should be done when<br>
<pre wrap=3D""> - (1) no private or protected non-static data members=
and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
Vicente
</pre>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------070800010509000506090405--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Tue, 5 Jan 2016 23:44:07 +0100
Raw View
Le 05/01/2016 04:08, Ville Voutilainen a =C3=A9crit :
> On 5 January 2016 at 02:26, Vicente J. Botet Escriba
> <vicente.botet@wanadoo.fr> wrote:
>> BTW, how can I check if a class is an aggregate?
>> array type
>> class type (typically, struct or union), that has
>> (1) no private or protected non-static data members
>> (2) no user-provided constructors (explicitly defaulted or deleted
>> constructors are allowed) (since C++11)
>> (3) no base classes
>> (4) no virtual member functions
>> With reflection n4428 API I don't see how to check for (4). (2) would ne=
ed
> is_polymorphic can check for it. The question is why would you check
> for an aggregate?
>
You are right. Please see the other post.
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 6 Jan 2016 02:10:34 +0100
Raw View
This is a multi-part message in MIME format.
--------------090002050201090608050102
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 05/01/2016 23:08, Vicente J. Botet Escriba a =C3=A9crit :
> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke wrote:
>>
>> On 2016-01-05 11:00, Nicol Bolas wrote:
>> > On 2016-01-04 22:08, Ville Voutilainen wrote:
>> >>> The question is why would you check for an aggregate?
>> >>
>> >> The goal is that get<N> would be implicitly defined for any
>> "aggregate".
>> >> It should *not* be defined however for types that have non-public
>> >> NSDM's. The question is how to achieve this.
>> >>
>> >> I should note that one answer is "compiler magic". If a
>> standard trait
>> >> is going to be a problem, that may be a strong argument to use
>> compiler
>> >> magic rather than a portable library solution.
>> >
>> > Well, reflection of any kind, which this whole idea relies on,
>> is going to
>> > require compiler magic.
>>
>> True. The question could be better expressed as whether the compiler
>> magic provides get<N> *directly* (as in, there may be no visible
>> declaration of the generic form of such), or whether get<N> is
>> (visibly,
>> in the standard library) implemented with the help of traits (which
>> themselves are compiler magic, but have broader applicability).
>>
>>
>> I say let the whole thing be compiler magic. It'd probably be faster=20
>> to compile that way if the compiler can just use intrinsics or=20
>> whatever to enumerate the members of the struct.
>>
> Thanks to all for your help. Could we conclude then that the=20
> generation should be done when
> - (1) no private or protected non-static data members and
> - (2) no base classes
This could be relaxed to having no more than 1 public base class, such=20
that the base class satisfy the same constraints. Having two base=20
classes makes it difficult to have a coherent access to the members of=20
the second class.
> ?
>
> Do you see a better characterization?
>
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------090002050201090608050102
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 05/01/2016 23:08, Vicente J. Botet
Escriba a =C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:568C3EC7.8070900@wanadoo.fr" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Ty=
pe">
<div class=3D"moz-cite-prefix">Le 05/01/2016 19:20, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:487ea013-6fcb-4d2e-8bc7-8fe96cdbf0a9@isocpp.org"
type=3D"cite">On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5,
Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On
2016-01-05 11:00, Nicol Bolas wrote: <br>
> On 2016-01-04 22:08, Ville Voutilainen wrote: <br>
>>> The question is why would you check for an
aggregate? <br>
>> <br>
>> The goal is that get<N> would be implicitly
defined for any "aggregate". <br>
>> It should *not* be defined however for types that
have non-public <br>
>> NSDM's. The question is how to achieve this. <br>
>> <br>
>> I should note that one answer is "compiler magic". If
a standard trait <br>
>> is going to be a problem, that may be a strong
argument to use compiler <br>
>> magic rather than a portable library solution. <br>
> <br>
> Well, reflection of any kind, which this whole idea
relies on, is going to <br>
> require compiler magic. <br>
<br>
True. The question could be better expressed as whether the
compiler <br>
magic provides get<N> *directly* (as in, there may be no
visible <br>
declaration of the generic form of such), or whether
get<N> is (visibly, <br>
in the standard library) implemented with the help of traits
(which <br>
themselves are compiler magic, but have broader
applicability). <br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic. It'd probably be
faster to compile that way if the compiler can just use
intrinsics or whatever to enumerate the members of the struct.<br=
>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude then that the
generation should be done when<br>
<pre wrap=3D""> - (1) no private or protected non-static data membe=
rs and
- (2) no base classes </pre>
</blockquote>
This could be relaxed to having no more than 1 public base class,
such that the base class satisfy the same constraints. Having two
base classes makes it difficult to have a coherent access to the
members of the second class.<br>
<blockquote cite=3D"mid:568C3EC7.8070900@wanadoo.fr" type=3D"cite">
<pre wrap=3D"">
?
Do you see a better characterization?
</pre>
</blockquote>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------090002050201090608050102--
.
Author: Greg Marr <gregmmarr@gmail.com>
Date: Tue, 5 Jan 2016 18:36:29 -0800 (PST)
Raw View
------=_Part_11902_240020352.1452047789762
Content-Type: multipart/alternative;
boundary="----=_Part_11903_1023226280.1452047789762"
------=_Part_11903_1023226280.1452047789762
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, January 5, 2016 at 8:10:37 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 05/01/2016 23:08, Vicente J. Botet Escriba a =C3=A9crit :
>
> Thanks to all for your help. Could we conclude then that the generation=
=20
> should be done when
>
> - (1) no private or protected non-static data members and
> - (2) no base classes=20
>
> This could be relaxed to having no more than 1 public base class, such=20
> that the base class satisfy the same constraints. Having two base classes=
=20
> makes it difficult to have a coherent access to the members of the second=
=20
> class.
>
If the issue with #1 is just about having a well-defined order for the data
members, then it could be relaxed to all non-static data members have
the same access. Not sure how useful that would be in practice though,
as this would generally be used outside the class.
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_11903_1023226280.1452047789762
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, January 5, 2016 at 8:10:37 PM UTC-5, 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 05/01/2016 23:08, Vicente J. Botet
Escriba a =C3=A9crit=C2=A0:</div><blockquote type=3D"cite">
=20
=20
Thanks to all for your help. Could we conclude then that the
generation should be done when<br>
<pre> - (1) no private or protected non-static data members and
- (2) no base classes </pre>
</blockquote>
This could be relaxed to having no more than 1 public base class,
such that the base class satisfy the same constraints. Having two
base classes makes it difficult to have a coherent access to the
members of the second class.<br></div></blockquote><div><br></div><div>=
If the issue with #1 is just about having a well-defined order for the data=
</div><div>members, then it could be relaxed to all non-static data members=
have</div><div>the same access. =C2=A0Not sure how useful that would be in=
practice though,</div><div>as this would generally be used outside the cla=
ss.</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_11903_1023226280.1452047789762--
------=_Part_11902_240020352.1452047789762--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 6 Jan 2016 09:24:34 +0100
Raw View
This is a multi-part message in MIME format.
--------------010900040107090409050802
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 06/01/2016 03:36, Greg Marr a =C3=A9crit :
> On Tuesday, January 5, 2016 at 8:10:37 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
> Le 05/01/2016 23:08, Vicente J. Botet Escriba a =C3=A9crit :
>> Thanks to all for your help. Could we conclude then that the
>> generation should be done when
>> - (1) no private or protected non-static data members and
>> - (2) no base classes
> This could be relaxed to having no more than 1 public base class,
> such that the base class satisfy the same constraints. Having two
> base classes makes it difficult to have a coherent access to the
> members of the second class.
>
>
> If the issue with #1 is just about having a well-defined order for the=20
> data
> members, then it could be relaxed to all non-static data members have
> the same access. Not sure how useful that would be in practice though,
> as this would generally be used outside the class.
>
Yes, the index <-> data member mapping must be trivial for the user. I=20
don't see why we could want to provide access to protected or private NSDM.
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------010900040107090409050802
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 06/01/2016 03:36, Greg Marr a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:0b4baca8-ad36-438c-bd56-cb0609a56d8c@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">On Tuesday, January 5, 2016 at 8:10:37 PM UTC-5,
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;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 05/01/2016 23:08, Vicente J. Botet Escriba a =C3=A9crit=
=C2=A0:</div>
<blockquote type=3D"cite"> Thanks to all for your help. Could
we conclude then that the generation should be done when<br>
<pre> - (1) no private or protected non-static data members=
and
- (2) no base classes </pre>
</blockquote>
This could be relaxed to having no more than 1 public base
class, such that the base class satisfy the same
constraints. Having two base classes makes it difficult to
have a coherent access to the members of the second class.<br>
</div>
</blockquote>
<div><br>
</div>
<div>If the issue with #1 is just about having a well-defined
order for the data</div>
<div>members, then it could be relaxed to all non-static data
members have</div>
<div>the same access. =C2=A0Not sure how useful that would be in
practice though,</div>
<div>as this would generally be used outside the class.</div>
</div>
<br>
</blockquote>
Yes, the index <-> data member mapping must be trivial for the
user. I don't see why we could want to provide access to protected
or private NSDM. <br>
<br>
Vicente <br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------010900040107090409050802--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 06 Jan 2016 11:08:20 -0500
Raw View
On 2016-01-05 17:08, Vicente J. Botet Escriba wrote:
> Thanks to all for your help. Could we conclude then that the generation
> should be done when
>
> - (1) no private or protected non-static data members and
> - (2) no base classes
> ?
>
> Do you see a better characterization?
On 2016-01-05 20:10, Vicente J. Botet Escriba wrote:
> This could be relaxed to having no more than 1 public base class, such
> that the base class satisfy the same constraints.
Yes, especially with aggregates being allowed base classes. Ideally,
being an aggregate should be *sufficient* (but not *necessary*) for
being tuple-like. That is, if a type T is an aggregate, then T is
tuple-like (unless get<0>(T) is explicitly deleted).
'T' is an aggregate => 'T' is tuple-like
'T' is (implicitly) tuple-like =/> 'T' is an aggregate'
(Read: "implies" (=>) and "does not imply" (=/>).)
> We can let the answer to whether it is the compiler that generates them
> or if they are generated using some missing type trait or reflection
> traits as an open question.
Agreed. I think it's okay to not specify this in the standard. It may
even be okay if different compilers/libraries do it differently, as long
as the end effect is the same.
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 06 Jan 2016 11:11:26 -0500
Raw View
On 2016-01-05 21:36, Greg Marr wrote:
> On Tuesday, January 5, 2016 at 8:10:37 PM UTC-5, Vicente J. Botet Escriba
> wrote:
>> Thanks to all for your help. Could we conclude then that the generation
>> should be done when
>>
>> - (1) no private or protected non-static data members and
>
> If the issue with #1 is just about having a well-defined order for the data
> members, then it could be relaxed to all non-static data members have
> the same access.
I'm not sure if I'm reading this right, but I'm pretty sure I disagree
in any case.
- A class's non-public members shall not be accessible via "tuple-like"
mechanisms. This should go without saying as it breaks encapsulation and
defeats the purpose of "non-public".
- A class with non-public NSDM's is almost certainly much more than the
sum of its public NSDM's, and therefore not likely to qualify
(conceptually) as "tuple like". I'd prefer that users must manually
provide tuple-like behavior for such classes.
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 6 Jan 2016 09:49:51 -0800 (PST)
Raw View
------=_Part_6476_410801061.1452102591578
Content-Type: multipart/alternative;
boundary="----=_Part_6477_20545299.1452102591578"
------=_Part_6477_20545299.1452102591578
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>
> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke wrote:=
=20
>>
>> On 2016-01-05 11:00, Nicol Bolas wrote:=20
>> > On 2016-01-04 22:08, Ville Voutilainen wrote:=20
>> >>> The question is why would you check for an aggregate?=20
>> >>=20
>> >> The goal is that get<N> would be implicitly defined for any=20
>> "aggregate".=20
>> >> It should *not* be defined however for types that have non-public=20
>> >> NSDM's. The question is how to achieve this.=20
>> >>=20
>> >> I should note that one answer is "compiler magic". If a standard trai=
t=20
>> >> is going to be a problem, that may be a strong argument to use=20
>> compiler=20
>> >> magic rather than a portable library solution.=20
>> >=20
>> > Well, reflection of any kind, which this whole idea relies on, is goin=
g=20
>> to=20
>> > require compiler magic.=20
>>
>> True. The question could be better expressed as whether the compiler=20
>> magic provides get<N> *directly* (as in, there may be no visible=20
>> declaration of the generic form of such), or whether get<N> is (visibly,=
=20
>> in the standard library) implemented with the help of traits (which=20
>> themselves are compiler magic, but have broader applicability).=20
>>
>
> I say let the whole thing be compiler magic. It'd probably be faster to=
=20
> compile that way if the compiler can just use intrinsics or whatever to=
=20
> enumerate the members of the struct.
>
> Thanks to all for your help. Could we conclude then that the generation=
=20
> should be done when
>
> - (1) no private or protected non-static data members and
> - (2) no base classes=20
> ?
>
> Do you see a better characterization?
>
> We can let the answer to whether it is the compiler that generates them o=
r if they are generated using some missing type trait or reflection traits =
as an open question. =20
>
>
> Vicente
>
>
I realized while reading your post that the structured bindings proposal=20
also keys off of being an aggregate when it is not, strictly speaking,=20
necessary.
That's when I started to think about what these limitations exist.
Aggregate initialization is all about the compiler generating construction=
=20
code on the fly. Looked at from that perspective, the reasoning for the=20
exclusions can be understood as follows:
1) *Types with constructors*: You're not supposed to be able to initialize=
=20
a type that has a user-provided constructor with anything *except* a call=
=20
to one of those constructors. That's how they maintain invariants.
2) *Public-only members*: Access classes exist so that only designated code=
=20
can access that value. So you can't initialize such values directly; only=
=20
designated code (ie: user-provided constructors) may do so.
3) *Virtual types*: Generating the construction code would require dealing=
=20
with filling in virtual stuff. That's more complex code which would best be=
=20
expressed with a constructor. Also, virtual stuff alters the layout of the=
=20
type.
4) *Types with base classes*: The layout of base classes is not=20
well-defined, which makes the initialization code more complex.
Notice that C++17 will dispense with #4, presumably because, well, what=20
does it matter? Yes, the layout is not defined by the standard, but every=
=20
class *has* a layout. The compiler knows what that layout is, so the=20
compiler can figure out how to put each item in the aggregate list in the=
=20
right place.
When initializing a type, restriction #3 matters, since you have to fill=20
out the appropriate information. But that information is irrelevant when=20
*accessing* NSDMs, either for these auto-tuplizing functions or for=20
structured binding.
(note: as I think more on this, it may be problematic with virtual=20
*inheritance*. But virtual functions themselves ought to be fine,=20
implementation-wise.)
So when doing structured binding or tuplized access, we should only require=
=20
restrictions #1 and #2 (and possibly no virtual inheritance).
Let us call this collection of types "publicly accessible". All of its=20
NSDMs are accessible to the public. Even though the layout isn't=20
necessarily specified by the standard, there is still a fixed,=20
well-understood layout for the type. As such, we can define a standard=20
ordering for the elements of such types, which is all that is needed for=20
auto-tuplizing or structured binding.
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_6477_20545299.1452102591578
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J. Botet Escriba w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 05/01/2016 19:20, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at 11:38:11 AM UT=
C-5,
Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex">On
2016-01-05 11:00, Nicol Bolas wrote:
<br>
> On 2016-01-04 22:08, Ville Voutilainen wrote: <br>
>>> The question is why would you check for an
aggregate? <br>
>>
<br>
>> The goal is that get<N> would be implicitly
defined for any "aggregate". <br>
>> It should *not* be defined however for types that have
non-public <br>
>> NSDM's. The question is how to achieve this. <br>
>>
<br>
>> I should note that one answer is "compiler magic"=
;. If a
standard trait <br>
>> is going to be a problem, that may be a strong argument
to use compiler <br>
>> magic rather than a portable library solution. <br>
> <br>
> Well, reflection of any kind, which this whole idea relies
on, is going to <br>
> require compiler magic.
<br>
<br>
True. The question could be better expressed as whether the
compiler
<br>
magic provides get<N> *directly* (as in, there may be no
visible
<br>
declaration of the generic form of such), or whether
get<N> is (visibly,
<br>
in the standard library) implemented with the help of traits
(which
<br>
themselves are compiler magic, but have broader applicability).
<br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic. It'd probably be
faster to compile that way if the compiler can just use
intrinsics or whatever to enumerate the members of the struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude then that the
generation should be done when<br>
<pre> - (1) no private or protected non-static data members and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
Vicente
</pre></div></blockquote><div><br>I realized while reading your post that t=
he structured bindings proposal also keys off of being an aggregate when it=
is not, strictly speaking, necessary.<br><br>That's when I started to =
think about what these limitations exist.<br><br>Aggregate initialization i=
s all about the compiler generating construction code on the fly. Looked at=
from that perspective, the reasoning for the exclusions can be understood =
as follows:<br><br>1) <b>Types with constructors</b>: You're not suppos=
ed to be able to initialize a type that has a user-provided constructor wit=
h anything <i>except</i> a call to one of those constructors. That's ho=
w they maintain invariants.<br>2) <b>Public-only members</b>: Access classe=
s exist so that only designated code can access that value. So you can'=
t initialize such values directly; only designated code (ie: user-provided =
constructors) may do so.<br>3) <b>Virtual types</b>: Generating the constru=
ction code would require dealing with filling in virtual stuff. That's =
more complex code which would best be expressed with a constructor. Also, v=
irtual stuff alters the layout of the type.<br>4) <b>Types with base classe=
s</b>: The layout of base classes is not well-defined, which makes the init=
ialization code more complex.<br><br>Notice that C++17 will dispense with #=
4, presumably because, well, what does it matter? Yes, the layout is not de=
fined by the standard, but every class <i>has</i> a layout. The compiler kn=
ows what that layout is, so the compiler can figure out how to put each ite=
m in the aggregate list in the right place.<br><br>When initializing a type=
, restriction #3 matters, since you have to fill out the appropriate inform=
ation. But that information is irrelevant when <i>accessing</i> NSDMs, eith=
er for these auto-tuplizing functions or for structured binding.<br><br>(no=
te: as I think more on this, it may be problematic with virtual <i>inherita=
nce</i>. But virtual functions themselves ought to be fine, implementation-=
wise.)<br><br>So when doing structured binding or tuplized access, we shoul=
d only require restrictions #1 and #2 (and possibly no virtual inheritance)=
..<br><br>Let us call this collection of types "publicly accessible&quo=
t;. All of its NSDMs are accessible to the public. Even though the layout i=
sn't necessarily specified by the standard, there is still a fixed, wel=
l-understood layout for the type. As such, we can define a standard orderin=
g for the elements of such types, which is all that is needed for auto-tupl=
izing or structured binding.<br></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_6477_20545299.1452102591578--
------=_Part_6476_410801061.1452102591578--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 06 Jan 2016 13:00:38 -0500
Raw View
On 2016-01-06 12:49, Nicol Bolas wrote:
> (note: as I think more on this, it may be problematic with virtual
> *inheritance*. But virtual functions themselves ought to be fine,
> implementation-wise.)
>
> So when doing structured binding or tuplized access, we should only require
> restrictions #1 and #2 (and possibly no virtual inheritance).
I want to say "yes", because virtual inheritance makes order unclear:
struct A { int a; }
struct B : virtual A {}
struct C : virtual A {}
struct D : A, B { int d; }
auto x = D{...};
get<1>(x); // A::a or D::d?
....but I don't see that applying if we also impose an
at-most-one-base-class limit, so it may actually be unnecessary.
Of course, if we *don't* imply an at-most-one-base-class restriction,
then I think we should (at least) forbid classes for which a virtual
base class appears more than once. (If we just forbid virtual bases,
period, that is okay too. Really, the main use case for this *is* going
to be for aggregate types. I don't see it as a major problem if there
are some corner cases that require the user to provide get<N>() for the
type.)
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 6 Jan 2016 19:13:45 +0100
Raw View
This is a multi-part message in MIME format.
--------------000402030500050505010405
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit :
> On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke
>> wrote:
>>
>> On 2016-01-05 11:00, Nicol Bolas wrote:
>> > On 2016-01-04 22:08, Ville Voutilainen wrote:
>> >>> The question is why would you check for an aggregate?
>> >>
>> >> The goal is that get<N> would be implicitly defined for
>> any "aggregate".
>> >> It should *not* be defined however for types that have
>> non-public
>> >> NSDM's. The question is how to achieve this.
>> >>
>> >> I should note that one answer is "compiler magic". If a
>> standard trait
>> >> is going to be a problem, that may be a strong argument to
>> use compiler
>> >> magic rather than a portable library solution.
>> >
>> > Well, reflection of any kind, which this whole idea relies
>> on, is going to
>> > require compiler magic.
>>
>> True. The question could be better expressed as whether the
>> compiler
>> magic provides get<N> *directly* (as in, there may be no visible
>> declaration of the generic form of such), or whether get<N>
>> is (visibly,
>> in the standard library) implemented with the help of traits
>> (which
>> themselves are compiler magic, but have broader applicability).
>>
>>
>> I say let the whole thing be compiler magic. It'd probably be
>> faster to compile that way if the compiler can just use
>> intrinsics or whatever to enumerate the members of the struct.
>>
> Thanks to all for your help. Could we conclude then that the
> generation should be done when
>
> - (1) no private or protected non-static data members and
> - (2) no base classes
> ?
>
> Do you see a better characterization?
>
> We can let the answer to whether it is the compiler that generates th=
em or if they are generated using some missing type trait or reflection tra=
its as an open question.
>
>
> I realized while reading your post that the structured bindings=20
> proposal also keys off of being an aggregate when it is not, strictly=20
> speaking, necessary.
>
> That's when I started to think about what these limitations exist.
>
> Aggregate initialization is all about the compiler generating=20
> construction code on the fly. Looked at from that perspective, the=20
> reasoning for the exclusions can be understood as follows:
>
> 1) *Types with constructors*: You're not supposed to be able to=20
> initialize a type that has a user-provided constructor with anything=20
> /except/ a call to one of those constructors. That's how they maintain=20
> invariants.
> 2) *Public-only members*: Access classes exist so that only designated=20
> code can access that value. So you can't initialize such values=20
> directly; only designated code (ie: user-provided constructors) may do so=
..
> 3) *Virtual types*: Generating the construction code would require=20
> dealing with filling in virtual stuff. That's more complex code which=20
> would best be expressed with a constructor. Also, virtual stuff alters=20
> the layout of the type.
> 4) *Types with base classes*: The layout of base classes is not=20
> well-defined, which makes the initialization code more complex.
>
> Notice that C++17 will dispense with #4, presumably because, well,=20
> what does it matter? Yes, the layout is not defined by the standard,=20
> but every class /has/ a layout. The compiler knows what that layout=20
> is, so the compiler can figure out how to put each item in the=20
> aggregate list in the right place.
>
> When initializing a type, restriction #3 matters, since you have to=20
> fill out the appropriate information. But that information is=20
> irrelevant when /accessing/ NSDMs, either for these auto-tuplizing=20
> functions or for structured binding.
>
> (note: as I think more on this, it may be problematic with virtual=20
> /inheritance/. But virtual functions themselves ought to be fine,=20
> implementation-wise.)
>
> So when doing structured binding or tuplized access, we should only=20
> require restrictions #1 and #2 (and possibly no virtual inheritance).
I missed why you want to maintain #1. This will eliminate std::tuple and=20
std::pair :(
I wonder about multiple inheritance. if
struct A: A1, A2 {...};
Is everyone comfortable with
get<0>(a) !=3D get<0>(static_cast<A2&>(a)
BTW, what would get<0>(a) be? static_cast<A1&>(a) or=20
get<0>(static_cast<A1&>(a))?
If we want that this applies to the current access for std::tuple the=20
answer should be get<0>(static_cast<A1&>(a)).
>
> Let us call this collection of types "publicly accessible". All of its=20
> NSDMs are accessible to the public. Even though the layout isn't=20
> necessarily specified by the standard, there is still a fixed,=20
> well-understood layout for the type. As such, we can define a standard=20
> ordering for the elements of such types, which is all that is needed=20
> for auto-tuplizing or structured binding.
>
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------000402030500050505010405
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 06/01/2016 18:49, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:a6ad88f3-2309-499a-aeca-834ecb0dfd0d@isocpp.org"
type=3D"cite">On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5,
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;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at
11:38:11 AM UTC-5, Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote"
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
solid;padding-left:1ex">On 2016-01-05 11:00, Nicol Bolas
wrote: <br>
> On 2016-01-04 22:08, Ville Voutilainen wrote: <br>
>>> The question is why would you check for an
aggregate? <br>
>> <br>
>> The goal is that get<N> would be implicitly
defined for any "aggregate". <br>
>> It should *not* be defined however for types that
have non-public <br>
>> NSDM's. The question is how to achieve this. <br>
>> <br>
>> I should note that one answer is "compiler
magic". If a standard trait <br>
>> is going to be a problem, that may be a strong
argument to use compiler <br>
>> magic rather than a portable library solution. <br>
> <br>
> Well, reflection of any kind, which this whole idea
relies on, is going to <br>
> require compiler magic. <br>
<br>
True. The question could be better expressed as whether
the compiler <br>
magic provides get<N> *directly* (as in, there may
be no visible <br>
declaration of the generic form of such), or whether
get<N> is (visibly, <br>
in the standard library) implemented with the help of
traits (which <br>
themselves are compiler magic, but have broader
applicability). <br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic. It'd probably
be faster to compile that way if the compiler can just use
intrinsics or whatever to enumerate the members of the
struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude then that the
generation should be done when<br>
<pre> - (1) no private or protected non-static data members and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
</pre>
</div>
</blockquote>
<div>I realized while reading your post that the structured
bindings proposal also keys off of being an aggregate when it is
not, strictly speaking, necessary.<br>
<br>
That's when I started to think about what these limitations
exist.<br>
<br>
Aggregate initialization is all about the compiler generating
construction code on the fly. Looked at from that perspective,
the reasoning for the exclusions can be understood as follows:<br>
<br>
1) <b>Types with constructors</b>: You're not supposed to be
able to initialize a type that has a user-provided constructor
with anything <i>except</i> a call to one of those
constructors. That's how they maintain invariants.<br>
2) <b>Public-only members</b>: Access classes exist so that
only designated code can access that value. So you can't
initialize such values directly; only designated code (ie:
user-provided constructors) may do so.<br>
3) <b>Virtual types</b>: Generating the construction code would
require dealing with filling in virtual stuff. That's more
complex code which would best be expressed with a constructor.
Also, virtual stuff alters the layout of the type.<br>
4) <b>Types with base classes</b>: The layout of base classes
is not well-defined, which makes the initialization code more
complex.<br>
<br>
Notice that C++17 will dispense with #4, presumably because,
well, what does it matter? Yes, the layout is not defined by the
standard, but every class <i>has</i> a layout. The compiler
knows what that layout is, so the compiler can figure out how to
put each item in the aggregate list in the right place.<br>
<br>
When initializing a type, restriction #3 matters, since you have
to fill out the appropriate information. But that information is
irrelevant when <i>accessing</i> NSDMs, either for these
auto-tuplizing functions or for structured binding.<br>
<br>
(note: as I think more on this, it may be problematic with
virtual <i>inheritance</i>. But virtual functions themselves
ought to be fine, implementation-wise.)<br>
<br>
So when doing structured binding or tuplized access, we should
only require restrictions #1 and #2 (and possibly no virtual
inheritance).<br>
</div>
</blockquote>
I missed why you want to maintain #1. This will eliminate std::tuple
and std::pair :(<br>
<br>
I wonder about multiple inheritance. if <br>
<br>
=C2=A0=C2=A0=C2=A0 struct A: A1, A2 {...};<br>
<br>
Is everyone comfortable with <br>
<br>
=C2=A0=C2=A0=C2=A0 get<0>(a) !=3D get<0>(static_cast<A2&=
amp;>(a)<br>
<br>
BTW, what would get<0>(a) be? static_cast<A1&>(a) or
get<0>(static_cast<A1&>(a))?<br>
<br>
If we want that this applies to the current access for std::tuple
the answer should be get<0>(static_cast<A1&>(a)).<br>
<br>
<blockquote
cite=3D"mid:a6ad88f3-2309-499a-aeca-834ecb0dfd0d@isocpp.org"
type=3D"cite">
<div><br>
Let us call this collection of types "publicly accessible". All
of its NSDMs are accessible to the public. Even though the
layout isn't necessarily specified by the standard, there is
still a fixed, well-understood layout for the type. As such, we
can define a standard ordering for the elements of such types,
which is all that is needed for auto-tuplizing or structured
binding.<br>
</div>
<br>
</blockquote>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------000402030500050505010405--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 06 Jan 2016 13:40:25 -0500
Raw View
On 2016-01-06 13:13, Vicente J. Botet Escriba wrote:
> Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit :
>> 1) *Types with constructors*: You're not supposed to be able to
>> initialize a type that has a user-provided constructor with anything
>> /except/ a call to one of those constructors. That's how they maintain
>> invariants.
>> 2) *Public-only members*: Access classes exist so that only designated
>> code can access that value. So you can't initialize such values
>> directly; only designated code (ie: user-provided constructors) may do
>> so.
>> [...]
>> So when doing structured binding or tuplized access, we should only
>> require restrictions #1 and #2 (and possibly no virtual inheritance).
>
> I missed why you want to maintain #1. This will eliminate std::tuple and
> std::pair :(
Heh. I didn't catch that, but now that you point it out, me too.
Especially as Nicol said previously:
On 2016-01-04 21:52, Nicol Bolas wrote:
> And what's the point of the constructor limitation?
Maybe an oversight?
> I wonder about multiple inheritance. if
>=20
> struct A: A1, A2 {...};
>=20
> Is everyone comfortable with
>=20
> get<0>(a) !=3D get<0>(static_cast<A2&>(a)
*IF* we allow multiple inheritance, that's what I would expect. I'm less
convinced that we need to (see also my previous post).
> BTW, what would get<0>(a) be? static_cast<A1&>(a) or
> get<0>(static_cast<A1&>(a))?
The latter, please :-). The latter makes much more sense when
subclassing is seen as extending the type, which is what is usually done
when we're talking about aggregates. For example:
struct A { int a; }
struct B : A { int b; }
....to access the member A::a from an instance of a B, you write '.a',
not '.A.a' or some such (usually).
Continuing the example:
struct A { int s, t; }
struct B : A { int x, y; }
auto x =3D B{...};
get<0>(x); // -> A::s
get<1>(x); // -> A::t
get<2>(x); // -> B::x
get<3>(x); // -> B::y
--=20
Matthew
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 6 Jan 2016 10:40:56 -0800 (PST)
Raw View
------=_Part_53_583534280.1452105657053
Content-Type: multipart/alternative;
boundary="----=_Part_54_1247374328.1452105657053"
------=_Part_54_1247374328.1452105657053
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, January 6, 2016 at 1:13:48 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit :
>
> On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J. Botet Escriba=
=20
> wrote:=20
>>
>> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>>
>> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke wrote:=
=20
>>>
>>> On 2016-01-05 11:00, Nicol Bolas wrote:=20
>>> > On 2016-01-04 22:08, Ville Voutilainen wrote:=20
>>> >>> The question is why would you check for an aggregate?=20
>>> >>=20
>>> >> The goal is that get<N> would be implicitly defined for any=20
>>> "aggregate".=20
>>> >> It should *not* be defined however for types that have non-public=20
>>> >> NSDM's. The question is how to achieve this.=20
>>> >>=20
>>> >> I should note that one answer is "compiler magic". If a standard=20
>>> trait=20
>>> >> is going to be a problem, that may be a strong argument to use=20
>>> compiler=20
>>> >> magic rather than a portable library solution.=20
>>> >=20
>>> > Well, reflection of any kind, which this whole idea relies on, is=20
>>> going to=20
>>> > require compiler magic.=20
>>>
>>> True. The question could be better expressed as whether the compiler=20
>>> magic provides get<N> *directly* (as in, there may be no visible=20
>>> declaration of the generic form of such), or whether get<N> is (visibly=
,=20
>>> in the standard library) implemented with the help of traits (which=20
>>> themselves are compiler magic, but have broader applicability).=20
>>>
>>
>> I say let the whole thing be compiler magic. It'd probably be faster to=
=20
>> compile that way if the compiler can just use intrinsics or whatever to=
=20
>> enumerate the members of the struct.
>>
>> Thanks to all for your help. Could we conclude then that the generation=
=20
>> should be done when
>>
>> - (1) no private or protected non-static data members and
>> - (2) no base classes=20
>> ?
>>
>> Do you see a better characterization?
>>
>> We can let the answer to whether it is the compiler that generates them =
or if they are generated using some missing type trait or reflection traits=
as an open question. =20
>>
>>
>>
>> I realized while reading your post that the structured bindings proposal=
=20
> also keys off of being an aggregate when it is not, strictly speaking,=20
> necessary.
>
> That's when I started to think about what these limitations exist.
>
> Aggregate initialization is all about the compiler generating constructio=
n=20
> code on the fly. Looked at from that perspective, the reasoning for the=
=20
> exclusions can be understood as follows:
>
> 1) *Types with constructors*: You're not supposed to be able to=20
> initialize a type that has a user-provided constructor with anything=20
> *except* a call to one of those constructors. That's how they maintain=20
> invariants.
> 2) *Public-only members*: Access classes exist so that only designated=20
> code can access that value. So you can't initialize such values directly;=
=20
> only designated code (ie: user-provided constructors) may do so.
> 3) *Virtual types*: Generating the construction code would require=20
> dealing with filling in virtual stuff. That's more complex code which wou=
ld=20
> best be expressed with a constructor. Also, virtual stuff alters the layo=
ut=20
> of the type.
> 4) *Types with base classes*: The layout of base classes is not=20
> well-defined, which makes the initialization code more complex.
>
> Notice that C++17 will dispense with #4, presumably because, well, what=
=20
> does it matter? Yes, the layout is not defined by the standard, but every=
=20
> class *has* a layout. The compiler knows what that layout is, so the=20
> compiler can figure out how to put each item in the aggregate list in the=
=20
> right place.
>
> When initializing a type, restriction #3 matters, since you have to fill=
=20
> out the appropriate information. But that information is irrelevant when=
=20
> *accessing* NSDMs, either for these auto-tuplizing functions or for=20
> structured binding.
>
> (note: as I think more on this, it may be problematic with virtual=20
> *inheritance*. But virtual functions themselves ought to be fine,=20
> implementation-wise.)
>
> So when doing structured binding or tuplized access, we should only=20
> require restrictions #1 and #2 (and possibly no virtual inheritance).
>
> I missed why you want to maintain #1. This will eliminate std::tuple and=
=20
> std::pair :(
>
They already have tuple-like interfaces. And structured binding will=20
already need an extensibility mechanism for types that don't fit this=20
criteria.
So just apply those to `tuple` and `pair`.
=20
> I wonder about multiple inheritance. if=20
>
> struct A: A1, A2 {...};
>
> Is everyone comfortable with=20
>
> get<0>(a) !=3D get<0>(static_cast<A2&>(a)
>
Yes. It matches with aggregate initialization in C++17.
=20
> BTW, what would get<0>(a) be? static_cast<A1&>(a) or=20
> get<0>(static_cast<A1&>(a))?
>
The same thing it is in aggregate initialization in C++17.
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_54_1247374328.1452105657053
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, January 6, 2016 at 1:13:48 PM UTC-5, 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 06/01/2016 18:49, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at 5:08:09 PM UTC=
-5,
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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at
11:38:11 AM UTC-5, Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left=
:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 2016-01-05 11:00, Ni=
col Bolas
wrote: <br>
> On 2016-01-04 22:08, Ville Voutilainen wrote: <br>
>>> The question is why would you check for an
aggregate? <br>
>> <br>
>> The goal is that get<N> would be implicitly
defined for any "aggregate". <br>
>> It should *not* be defined however for types that
have non-public <br>
>> NSDM's. The question is how to achieve this. <br=
>
>> <br>
>> I should note that one answer is "compiler
magic". If a standard trait <br>
>> is going to be a problem, that may be a strong
argument to use compiler <br>
>> magic rather than a portable library solution. <br>
> <br>
> Well, reflection of any kind, which this whole idea
relies on, is going to <br>
> require compiler magic. <br>
<br>
True. The question could be better expressed as whether
the compiler <br>
magic provides get<N> *directly* (as in, there may
be no visible <br>
declaration of the generic form of such), or whether
get<N> is (visibly, <br>
in the standard library) implemented with the help of
traits (which <br>
themselves are compiler magic, but have broader
applicability). <br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic. It'd probabl=
y
be faster to compile that way if the compiler can just use
intrinsics or whatever to enumerate the members of the
struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude then that the
generation should be done when<br>
<pre> - (1) no private or protected non-static data members and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
</pre>
</div>
</blockquote>
<div>I realized while reading your post that the structured
bindings proposal also keys off of being an aggregate when it is
not, strictly speaking, necessary.<br>
<br>
That's when I started to think about what these limitations
exist.<br>
<br>
Aggregate initialization is all about the compiler generating
construction code on the fly. Looked at from that perspective,
the reasoning for the exclusions can be understood as follows:<br>
<br>
1) <b>Types with constructors</b>: You're not supposed to be
able to initialize a type that has a user-provided constructor
with anything <i>except</i> a call to one of those
constructors. That's how they maintain invariants.<br>
2) <b>Public-only members</b>: Access classes exist so that
only designated code can access that value. So you can't
initialize such values directly; only designated code (ie:
user-provided constructors) may do so.<br>
3) <b>Virtual types</b>: Generating the construction code would
require dealing with filling in virtual stuff. That's more
complex code which would best be expressed with a constructor.
Also, virtual stuff alters the layout of the type.<br>
4) <b>Types with base classes</b>: The layout of base classes
is not well-defined, which makes the initialization code more
complex.<br>
<br>
Notice that C++17 will dispense with #4, presumably because,
well, what does it matter? Yes, the layout is not defined by the
standard, but every class <i>has</i> a layout. The compiler
knows what that layout is, so the compiler can figure out how to
put each item in the aggregate list in the right place.<br>
<br>
When initializing a type, restriction #3 matters, since you have
to fill out the appropriate information. But that information is
irrelevant when <i>accessing</i> NSDMs, either for these
auto-tuplizing functions or for structured binding.<br>
<br>
(note: as I think more on this, it may be problematic with
virtual <i>inheritance</i>. But virtual functions themselves
ought to be fine, implementation-wise.)<br>
<br>
So when doing structured binding or tuplized access, we should
only require restrictions #1 and #2 (and possibly no virtual
inheritance).<br>
</div>
</blockquote>
I missed why you want to maintain #1. This will eliminate std::tuple
and std::pair :(<br></div></blockquote><div><br>They already have tuple=
-like interfaces. And structured binding will already need an extensibility=
mechanism for types that don't fit this criteria.<br><br>So just apply=
those to `tuple` and `pair`.<br>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
=20
I wonder about multiple inheritance. if <br>
<br>
=C2=A0=C2=A0=C2=A0 struct A: A1, A2 {...};<br>
<br>
Is everyone comfortable with <br>
<br>
=C2=A0=C2=A0=C2=A0 get<0>(a) !=3D get<0>(static_cast<A2&=
amp;>(a)<br></div></blockquote><div><br>Yes. It matches with aggregate i=
nitialization in C++17.<br>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
=20
BTW, what would get<0>(a) be? static_cast<A1&>(a) or
get<0>(static_cast<A1&>(a))?<br></div></blockquote><div=
><br>The same thing it is in aggregate initialization in C++17.<br></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_54_1247374328.1452105657053--
------=_Part_53_583534280.1452105657053--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 6 Jan 2016 10:42:36 -0800 (PST)
Raw View
------=_Part_135_2074133756.1452105756786
Content-Type: multipart/alternative;
boundary="----=_Part_136_862000533.1452105756786"
------=_Part_136_862000533.1452105756786
Content-Type: text/plain; charset=UTF-8
On Wednesday, January 6, 2016 at 1:01:01 PM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-06 12:49, Nicol Bolas wrote:
> > (note: as I think more on this, it may be problematic with virtual
> > *inheritance*. But virtual functions themselves ought to be fine,
> > implementation-wise.)
> >
> > So when doing structured binding or tuplized access, we should only
> require
> > restrictions #1 and #2 (and possibly no virtual inheritance).
>
> I want to say "yes", because virtual inheritance makes order unclear:
>
> struct A { int a; }
> struct B : virtual A {}
> struct C : virtual A {}
> struct D : A, B { int d; }
>
> auto x = D{...};
> get<1>(x); // A::a or D::d?
>
> ...but I don't see that applying if we also impose an
> at-most-one-base-class limit, so it may actually be unnecessary.
>
> Of course, if we *don't* imply an at-most-one-base-class restriction,
> then I think we should (at least) forbid classes for which a virtual
> base class appears more than once. (If we just forbid virtual bases,
> period, that is okay too. Really, the main use case for this *is* going
> to be for aggregate types. I don't see it as a major problem if there
> are some corner cases that require the user to provide get<N>() for the
> type.)
>
OK, just forbid virtual bases. Nobody liked them anyway ;)
If we think of structured binding and tuple access to be the inverse of
aggregate initialization, then we should support at least whatever types
fit the C++17 rules for aggregate initialization. We can support more, but
we should never support fewer.
And C++17 aggregate initialization allows multiple base classes.
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_136_862000533.1452105756786
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Wednesday, January 6, 2016 at 1:01:01 PM UTC-5, Matthew Woehlke =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-06 12:49, Nic=
ol Bolas wrote:
<br>> (note: as I think more on this, it may be problematic with virtual=
=20
<br>> *inheritance*. But virtual functions themselves ought to be fine,=
=20
<br>> implementation-wise.)
<br>>=20
<br>> So when doing structured binding or tuplized access, we should onl=
y require=20
<br>> restrictions #1 and #2 (and possibly no virtual inheritance).
<br>
<br>I want to say "yes", because virtual inheritance makes order =
unclear:
<br>
<br>=C2=A0 struct A { int a; }
<br>=C2=A0 struct B : virtual A {}
<br>=C2=A0 struct C : virtual A {}
<br>=C2=A0 struct D : A, B { int d; }
<br>
<br>=C2=A0 auto x =3D D{...};
<br>=C2=A0 get<1>(x); // A::a or D::d?
<br>
<br>...but I don't see that applying if we also impose an
<br>at-most-one-base-class limit, so it may actually be unnecessary.
<br>
<br>Of course, if we *don't* imply an at-most-one-base-class restrictio=
n,
<br>then I think we should (at least) forbid classes for which a virtual
<br>base class appears more than once. (If we just forbid virtual bases,
<br>period, that is okay too. Really, the main use case for this *is* going
<br>to be for aggregate types. I don't see it as a major problem if the=
re
<br>are some corner cases that require the user to provide get<N>() f=
or the
<br>type.)<br></blockquote><div><br>OK, just forbid virtual bases. Nobody l=
iked them anyway ;)<br><br>If we think of structured binding and tuple acce=
ss to be the inverse of aggregate initialization, then we should support at=
least whatever types fit the C++17 rules for aggregate initialization. We =
can support more, but we should never support fewer.<br><br>And C++17 aggre=
gate initialization allows multiple base classes.</div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_136_862000533.1452105756786--
------=_Part_135_2074133756.1452105756786--
.
Author: Greg Marr <gregmmarr@gmail.com>
Date: Wed, 6 Jan 2016 11:24:41 -0800 (PST)
Raw View
------=_Part_884_513912793.1452108281540
Content-Type: multipart/alternative;
boundary="----=_Part_885_472558973.1452108281540"
------=_Part_885_472558973.1452108281540
Content-Type: text/plain; charset=UTF-8
On Wednesday, January 6, 2016 at 11:15:08 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-05 21:36, Greg Marr wrote:
> > On Tuesday, January 5, 2016 at 8:10:37 PM UTC-5, Vicente J. Botet
> Escriba
> > wrote:
> >> Thanks to all for your help. Could we conclude then that the generation
> >> should be done when
> >>
> >> - (1) no private or protected non-static data members and
> >
> > If the issue with #1 is just about having a well-defined order for the
> data
> > members, then it could be relaxed to all non-static data members have
> > the same access.
>
> I'm not sure if I'm reading this right, but I'm pretty sure I disagree
> in any case.
>
> - A class's non-public members shall not be accessible via "tuple-like"
> mechanisms. This should go without saying as it breaks encapsulation and
> defeats the purpose of "non-public".
>
This would obviously have to not bypass access protection.
> - A class with non-public NSDM's is almost certainly much more than the
> sum of its public NSDM's, and therefore not likely to qualify
> (conceptually) as "tuple like". I'd prefer that users must manually
> provide tuple-like behavior for such classes.
>
That sounds reasonable.
I was just noting that the order of members is well defined as long as they
all have the same access. I couldn't really come up with a good reason
that someone might want it and actually be able to use it. These are all
good reasons to include with a proposal that says "only public data
members", to indicate that it's not just about well defined order.
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_885_472558973.1452108281540
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, January 6, 2016 at 11:15:08 AM UTC-5, Matthew Woehlke wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-05 21:36, Greg Marr =
wrote:
<br>> On Tuesday, January 5, 2016 at 8:10:37 PM UTC-5, Vicente J. Botet =
Escriba=20
<br>> wrote:
<br>>> Thanks to all for your help. Could we conclude then that the g=
eneration=20
<br>>> should be done when
<br>>>
<br>>> =C2=A0 =C2=A0- (1) no private or protected non-static data mem=
bers and
<br>>=20
<br>> If the issue with #1 is just about having a well-defined order for=
the data
<br>> members, then it could be relaxed to all non-static data members h=
ave
<br>> the same access.
<br>
<br>I'm not sure if I'm reading this right, but I'm pretty sure=
I disagree
<br>in any case.
<br>
<br>- A class's non-public members shall not be accessible via "tu=
ple-like"
<br>mechanisms. This should go without saying as it breaks encapsulation an=
d
<br>defeats the purpose of "non-public".
<br></blockquote><div><br></div><div>This would obviously have to not bypas=
s access protection.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;">- A class with non-public NSDM's is almost certainly much =
more than the
<br>sum of its public NSDM's, and therefore not likely to qualify
<br>(conceptually) as "tuple like". I'd prefer that users mus=
t manually
<br>provide tuple-like behavior for such classes.
<br></blockquote><div><br></div><div>That sounds reasonable.</div><div><br>=
</div><div>I was just noting that the order of members is well defined as l=
ong as they</div><div>all have the same access. =C2=A0I couldn't really=
come up with a good reason</div><div>that someone might want it and actual=
ly be able to use it. =C2=A0These are all</div><div>good reasons to include=
with a proposal that says "only public data</div><div>members", =
to indicate that it's not just about well defined order.</div><div><br>=
</div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_885_472558973.1452108281540--
------=_Part_884_513912793.1452108281540--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 6 Jan 2016 22:57:43 +0100
Raw View
This is a multi-part message in MIME format.
--------------070905020002050608090405
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 06/01/2016 19:40, Nicol Bolas a =C3=A9crit :
> On Wednesday, January 6, 2016 at 1:13:48 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
> Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit :
>> On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J. Botet
>> Escriba wrote:
>>
>> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>>> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew
>>> Woehlke wrote:
>>>
>>> On 2016-01-05 11:00, Nicol Bolas wrote:
>>> > On 2016-01-04 22:08, Ville Voutilainen wrote:
>>> >>> The question is why would you check for an aggregate?
>>> >>
>>> >> The goal is that get<N> would be implicitly defined
>>> for any "aggregate".
>>> >> It should *not* be defined however for types that
>>> have non-public
>>> >> NSDM's. The question is how to achieve this.
>>> >>
>>> >> I should note that one answer is "compiler magic". If
>>> a standard trait
>>> >> is going to be a problem, that may be a strong
>>> argument to use compiler
>>> >> magic rather than a portable library solution.
>>> >
>>> > Well, reflection of any kind, which this whole idea
>>> relies on, is going to
>>> > require compiler magic.
>>>
>>> True. The question could be better expressed as whether
>>> the compiler
>>> magic provides get<N> *directly* (as in, there may be no
>>> visible
>>> declaration of the generic form of such), or whether
>>> get<N> is (visibly,
>>> in the standard library) implemented with the help of
>>> traits (which
>>> themselves are compiler magic, but have broader
>>> applicability).
>>>
>>>
>>> I say let the whole thing be compiler magic. It'd probably
>>> be faster to compile that way if the compiler can just use
>>> intrinsics or whatever to enumerate the members of the struct.
>>>
>> Thanks to all for your help. Could we conclude then that the
>> generation should be done when
>>
>> - (1) no private or protected non-static data members and
>> - (2) no base classes
>> ?
>>
>> Do you see a better characterization?
>>
>> We can let the answer to whether it is the compiler that generat=
es them or if they are generated using some missing type trait or reflectio=
n traits as an open question.
>>
>>
>> I realized while reading your post that the structured bindings
>> proposal also keys off of being an aggregate when it is not,
>> strictly speaking, necessary.
>>
>> That's when I started to think about what these limitations exist.
>>
>> Aggregate initialization is all about the compiler generating
>> construction code on the fly. Looked at from that perspective,
>> the reasoning for the exclusions can be understood as follows:
>>
>> 1) *Types with constructors*: You're not supposed to be able to
>> initialize a type that has a user-provided constructor with
>> anything /except/ a call to one of those constructors. That's how
>> they maintain invariants.
>> 2) *Public-only members*: Access classes exist so that only
>> designated code can access that value. So you can't initialize
>> such values directly; only designated code (ie: user-provided
>> constructors) may do so.
>> 3) *Virtual types*: Generating the construction code would
>> require dealing with filling in virtual stuff. That's more
>> complex code which would best be expressed with a constructor.
>> Also, virtual stuff alters the layout of the type.
>> 4) *Types with base classes*: The layout of base classes is not
>> well-defined, which makes the initialization code more complex.
>>
>> Notice that C++17 will dispense with #4, presumably because,
>> well, what does it matter? Yes, the layout is not defined by the
>> standard, but every class /has/ a layout. The compiler knows what
>> that layout is, so the compiler can figure out how to put each
>> item in the aggregate list in the right place.
>>
>> When initializing a type, restriction #3 matters, since you have
>> to fill out the appropriate information. But that information is
>> irrelevant when /accessing/ NSDMs, either for these
>> auto-tuplizing functions or for structured binding.
>>
>> (note: as I think more on this, it may be problematic with
>> virtual /inheritance/. But virtual functions themselves ought to
>> be fine, implementation-wise.)
>>
>> So when doing structured binding or tuplized access, we should
>> only require restrictions #1 and #2 (and possibly no virtual
>> inheritance).
> I missed why you want to maintain #1. This will eliminate
> std::tuple and std::pair :(
>
>
> They already have tuple-like interfaces. And structured binding will=20
> already need an extensibility mechanism for types that don't fit this=20
> criteria.
>
> So just apply those to `tuple` and `pair`.
Maybe, but why do you want to preserve #1?
>
> I wonder about multiple inheritance. if
>
> struct A: A1, A2 {...};
>
> Is everyone comfortable with
>
> get<0>(a) !=3D get<0>(static_cast<A2&>(a)
>
>
> Yes. It matches with aggregate initialization in C++17.
>
> BTW, what would get<0>(a) be? static_cast<A1&>(a) or
> get<0>(static_cast<A1&>(a))?
>
>
> The same thing it is in aggregate initialization in C++17.
>
You didn't replayed to my questions?
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------070905020002050608090405
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 06/01/2016 19:40, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:c087a17d-6ab0-40d3-acd7-e7c364edd388@isocpp.org"
type=3D"cite">On Wednesday, January 6, 2016 at 1:13:48 PM UTC-5,
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;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at 5:08:09
PM UTC-5, 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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit=C2=A0:<b=
r>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at
11:38:11 AM UTC-5, Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote"
style=3D"margin:0;margin-left:0.8ex;border-left:1px
#ccc solid;padding-left:1ex">On 2016-01-05 11:00,
Nicol Bolas wrote: <br>
> On 2016-01-04 22:08, Ville Voutilainen wrote: <br>
>>> The question is why would you check for
an aggregate? <br>
>> <br>
>> The goal is that get<N> would be
implicitly defined for any "aggregate". <br>
>> It should *not* be defined however for
types that have non-public <br>
>> NSDM's. The question is how to achieve
this. <br>
>> <br>
>> I should note that one answer is "compiler
magic". If a standard trait <br>
>> is going to be a problem, that may be a
strong argument to use compiler <br>
>> magic rather than a portable library
solution. <br>
> <br>
> Well, reflection of any kind, which this whole
idea relies on, is going to <br>
> require compiler magic. <br>
<br>
True. The question could be better expressed as
whether the compiler <br>
magic provides get<N> *directly* (as in, there
may be no visible <br>
declaration of the generic form of such), or whether
get<N> is (visibly, <br>
in the standard library) implemented with the help
of traits (which <br>
themselves are compiler magic, but have broader
applicability). <br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic. It'd
probably be faster to compile that way if the
compiler can just use intrinsics or whatever to
enumerate the members of the struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude then that
the generation should be done when<br>
<pre> - (1) no private or protected non-static data membe=
rs and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
</pre>
</div>
</blockquote>
<div>I realized while reading your post that the structured
bindings proposal also keys off of being an aggregate when
it is not, strictly speaking, necessary.<br>
<br>
That's when I started to think about what these
limitations exist.<br>
<br>
Aggregate initialization is all about the compiler
generating construction code on the fly. Looked at from
that perspective, the reasoning for the exclusions can be
understood as follows:<br>
<br>
1) <b>Types with constructors</b>: You're not supposed to
be able to initialize a type that has a user-provided
constructor with anything <i>except</i> a call to one of
those constructors. That's how they maintain invariants.<br>
2) <b>Public-only members</b>: Access classes exist so
that only designated code can access that value. So you
can't initialize such values directly; only designated
code (ie: user-provided constructors) may do so.<br>
3) <b>Virtual types</b>: Generating the construction code
would require dealing with filling in virtual stuff.
That's more complex code which would best be expressed
with a constructor. Also, virtual stuff alters the layout
of the type.<br>
4) <b>Types with base classes</b>: The layout of base
classes is not well-defined, which makes the
initialization code more complex.<br>
<br>
Notice that C++17 will dispense with #4, presumably
because, well, what does it matter? Yes, the layout is not
defined by the standard, but every class <i>has</i> a
layout. The compiler knows what that layout is, so the
compiler can figure out how to put each item in the
aggregate list in the right place.<br>
<br>
When initializing a type, restriction #3 matters, since
you have to fill out the appropriate information. But that
information is irrelevant when <i>accessing</i> NSDMs,
either for these auto-tuplizing functions or for
structured binding.<br>
<br>
(note: as I think more on this, it may be problematic with
virtual <i>inheritance</i>. But virtual functions
themselves ought to be fine, implementation-wise.)<br>
<br>
So when doing structured binding or tuplized access, we
should only require restrictions #1 and #2 (and possibly
no virtual inheritance).<br>
</div>
</blockquote>
I missed why you want to maintain #1. This will eliminate
std::tuple and std::pair :(<br>
</div>
</blockquote>
<div><br>
They already have tuple-like interfaces. And structured binding
will already need an extensibility mechanism for types that
don't fit this criteria.<br>
<br>
So just apply those to `tuple` and `pair`.<br>
</div>
</blockquote>
Maybe, but why do you want to preserve #1?<br>
<blockquote
cite=3D"mid:c087a17d-6ab0-40d3-acd7-e7c364edd388@isocpp.org"
type=3D"cite">
<div>=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 bgcolor=3D"#FFFFFF" text=3D"#000000"> I wonder about multiple
inheritance. if <br>
<br>
=C2=A0=C2=A0=C2=A0 struct A: A1, A2 {...};<br>
<br>
Is everyone comfortable with <br>
<br>
=C2=A0=C2=A0=C2=A0 get<0>(a) !=3D
get<0>(static_cast<A2&>(a)<br>
</div>
</blockquote>
<div><br>
Yes. It matches with aggregate initialization in C++17.<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 bgcolor=3D"#FFFFFF" text=3D"#000000"> BTW, what would
get<0>(a) be? static_cast<A1&>(a) or
get<0>(static_cast<A1&>(a))?<br>
</div>
</blockquote>
<div><br>
The same thing it is in aggregate initialization in C++17.<br>
</div>
<br>
</blockquote>
You didn't replayed to my questions? <br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------070905020002050608090405--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 6 Jan 2016 21:02:51 -0800 (PST)
Raw View
------=_Part_1145_483468076.1452142972091
Content-Type: multipart/alternative;
boundary="----=_Part_1146_1561077075.1452142972092"
------=_Part_1146_1561077075.1452142972092
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, January 6, 2016 at 4:57:47 PM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 06/01/2016 19:40, Nicol Bolas a =C3=A9crit :
>
> On Wednesday, January 6, 2016 at 1:13:48 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:=20
>>
>> Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit :
>>
>> On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J. Botet Escrib=
a=20
>> wrote:=20
>>>
>>> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>>>
>>> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke wrote=
:=20
>>>>
>>>> On 2016-01-05 11:00, Nicol Bolas wrote:=20
>>>> > On 2016-01-04 22:08, Ville Voutilainen wrote:=20
>>>> >>> The question is why would you check for an aggregate?=20
>>>> >>=20
>>>> >> The goal is that get<N> would be implicitly defined for any=20
>>>> "aggregate".=20
>>>> >> It should *not* be defined however for types that have non-public=
=20
>>>> >> NSDM's. The question is how to achieve this.=20
>>>> >>=20
>>>> >> I should note that one answer is "compiler magic". If a standard=20
>>>> trait=20
>>>> >> is going to be a problem, that may be a strong argument to use=20
>>>> compiler=20
>>>> >> magic rather than a portable library solution.=20
>>>> >=20
>>>> > Well, reflection of any kind, which this whole idea relies on, is=20
>>>> going to=20
>>>> > require compiler magic.=20
>>>>
>>>> True. The question could be better expressed as whether the compiler=
=20
>>>> magic provides get<N> *directly* (as in, there may be no visible=20
>>>> declaration of the generic form of such), or whether get<N> is=20
>>>> (visibly,=20
>>>> in the standard library) implemented with the help of traits (which=20
>>>> themselves are compiler magic, but have broader applicability).=20
>>>>
>>>
>>> I say let the whole thing be compiler magic. It'd probably be faster to=
=20
>>> compile that way if the compiler can just use intrinsics or whatever to=
=20
>>> enumerate the members of the struct.
>>>
>>> Thanks to all for your help. Could we conclude then that the generation=
=20
>>> should be done when
>>>
>>> - (1) no private or protected non-static data members and
>>> - (2) no base classes=20
>>> ?
>>>
>>> Do you see a better characterization?
>>>
>>> We can let the answer to whether it is the compiler that generates them=
or if they are generated using some missing type trait or reflection trait=
s as an open question. =20
>>>
>>>
>>>
>>> I realized while reading your post that the structured bindings proposa=
l=20
>> also keys off of being an aggregate when it is not, strictly speaking,=
=20
>> necessary.
>>
>> That's when I started to think about what these limitations exist.
>>
>> Aggregate initialization is all about the compiler generating=20
>> construction code on the fly. Looked at from that perspective, the=20
>> reasoning for the exclusions can be understood as follows:
>>
>> 1) *Types with constructors*: You're not supposed to be able to=20
>> initialize a type that has a user-provided constructor with anything=20
>> *except* a call to one of those constructors. That's how they maintain=
=20
>> invariants.
>> 2) *Public-only members*: Access classes exist so that only designated=
=20
>> code can access that value. So you can't initialize such values directly=
;=20
>> only designated code (ie: user-provided constructors) may do so.
>> 3) *Virtual types*: Generating the construction code would require=20
>> dealing with filling in virtual stuff. That's more complex code which wo=
uld=20
>> best be expressed with a constructor. Also, virtual stuff alters the lay=
out=20
>> of the type.
>> 4) *Types with base classes*: The layout of base classes is not=20
>> well-defined, which makes the initialization code more complex.
>>
>> Notice that C++17 will dispense with #4, presumably because, well, what=
=20
>> does it matter? Yes, the layout is not defined by the standard, but ever=
y=20
>> class *has* a layout. The compiler knows what that layout is, so the=20
>> compiler can figure out how to put each item in the aggregate list in th=
e=20
>> right place.
>>
>> When initializing a type, restriction #3 matters, since you have to fill=
=20
>> out the appropriate information. But that information is irrelevant when=
=20
>> *accessing* NSDMs, either for these auto-tuplizing functions or for=20
>> structured binding.
>>
>> (note: as I think more on this, it may be problematic with virtual=20
>> *inheritance*. But virtual functions themselves ought to be fine,=20
>> implementation-wise.)
>>
>> So when doing structured binding or tuplized access, we should only=20
>> require restrictions #1 and #2 (and possibly no virtual inheritance).
>>
>> I missed why you want to maintain #1. This will eliminate std::tuple and=
=20
>> std::pair :(
>>
>
> They already have tuple-like interfaces. And structured binding will=20
> already need an extensibility mechanism for types that don't fit this=20
> criteria.
>
> So just apply those to `tuple` and `pair`.
>
> Maybe, but why do you want to preserve #1?
>
First, `tuple` doesn't count, as its members are not required to be public,=
=20
nor are they required to be in the appropriate order. So they're going to=
=20
have to use its specialized getters no matter what.
As for the more general question... I suppose it is not *strictly*=20
necessary either. So long as *all* of the NSDMs are publicly accessible=20
(and no virtual inheritance), it could still work.
> =20
>
>> I wonder about multiple inheritance. if=20
>>
>> struct A: A1, A2 {...};
>>
>> Is everyone comfortable with=20
>>
>> get<0>(a) !=3D get<0>(static_cast<A2&>(a)
>>
>
> Yes. It matches with aggregate initialization in C++17.
> =20
>
>> BTW, what would get<0>(a) be? static_cast<A1&>(a) or=20
>> get<0>(static_cast<A1&>(a))?
>>
>
> The same thing it is in aggregate initialization in C++17.
>
> You didn't replayed to my questions?
>
I didn't? How not? I replied by saying "look at how aggregate=20
initialization in C++17 works. Make it work like that." That's the answer=
=20
I'm comfortable with.
Or let me put it another way. Given this:
SomeType aggregate =3D {val1, val2, val3, val4};
this ought to be true (reference types, movement, etc aside):
get<0>(aggregate) =3D=3D val1;
get<1>(aggregate) =3D=3D val2;
get<2>(aggregate) =3D=3D val3;
get<3>(aggregate) =3D=3D val4;
The index aggregate initialization would have used to set the value (even=
=20
if it's not, strictly speaking, an aggregate) is exactly the index that=20
tuple-based fetching should retrieve the value. And the same should go for=
=20
structured binding.
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_1146_1561077075.1452142972092
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, January 6, 2016 at 4:57:47 PM UTC-5, 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 06/01/2016 19:40, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Wednesday, January 6, 2016 at 1:13:48 PM U=
TC-5,
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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at 5:08:09
PM UTC-5, 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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit=C2=A0:<b=
r>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at
11:38:11 AM UTC-5, Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 2016-01-05 11:=
00,
Nicol Bolas wrote: <br>
> On 2016-01-04 22:08, Ville Voutilainen wrote: <br>
>>> The question is why would you check for
an aggregate? <br>
>> <br>
>> The goal is that get<N> would be
implicitly defined for any "aggregate". <br>
>> It should *not* be defined however for
types that have non-public <br>
>> NSDM's. The question is how to achieve
this. <br>
>> <br>
>> I should note that one answer is "compile=
r
magic". If a standard trait <br>
>> is going to be a problem, that may be a
strong argument to use compiler <br>
>> magic rather than a portable library
solution. <br>
> <br>
> Well, reflection of any kind, which this whole
idea relies on, is going to <br>
> require compiler magic. <br>
<br>
True. The question could be better expressed as
whether the compiler <br>
magic provides get<N> *directly* (as in, there
may be no visible <br>
declaration of the generic form of such), or whether
get<N> is (visibly, <br>
in the standard library) implemented with the help
of traits (which <br>
themselves are compiler magic, but have broader
applicability). <br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic. It'd
probably be faster to compile that way if the
compiler can just use intrinsics or whatever to
enumerate the members of the struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude then that
the generation should be done when<br>
<pre> - (1) no private or protected non-static data membe=
rs and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
</pre>
</div>
</blockquote>
<div>I realized while reading your post that the structured
bindings proposal also keys off of being an aggregate when
it is not, strictly speaking, necessary.<br>
<br>
That's when I started to think about what these
limitations exist.<br>
<br>
Aggregate initialization is all about the compiler
generating construction code on the fly. Looked at from
that perspective, the reasoning for the exclusions can be
understood as follows:<br>
<br>
1) <b>Types with constructors</b>: You're not supposed to
be able to initialize a type that has a user-provided
constructor with anything <i>except</i> a call to one of
those constructors. That's how they maintain invariants.<=
br>
2) <b>Public-only members</b>: Access classes exist so
that only designated code can access that value. So you
can't initialize such values directly; only designated
code (ie: user-provided constructors) may do so.<br>
3) <b>Virtual types</b>: Generating the construction code
would require dealing with filling in virtual stuff.
That's more complex code which would best be expressed
with a constructor. Also, virtual stuff alters the layout
of the type.<br>
4) <b>Types with base classes</b>: The layout of base
classes is not well-defined, which makes the
initialization code more complex.<br>
<br>
Notice that C++17 will dispense with #4, presumably
because, well, what does it matter? Yes, the layout is not
defined by the standard, but every class <i>has</i> a
layout. The compiler knows what that layout is, so the
compiler can figure out how to put each item in the
aggregate list in the right place.<br>
<br>
When initializing a type, restriction #3 matters, since
you have to fill out the appropriate information. But that
information is irrelevant when <i>accessing</i> NSDMs,
either for these auto-tuplizing functions or for
structured binding.<br>
<br>
(note: as I think more on this, it may be problematic with
virtual <i>inheritance</i>. But virtual functions
themselves ought to be fine, implementation-wise.)<br>
<br>
So when doing structured binding or tuplized access, we
should only require restrictions #1 and #2 (and possibly
no virtual inheritance).<br>
</div>
</blockquote>
I missed why you want to maintain #1. This will eliminate
std::tuple and std::pair :(<br>
</div>
</blockquote>
<div><br>
They already have tuple-like interfaces. And structured binding
will already need an extensibility mechanism for types that
don't fit this criteria.<br>
<br>
So just apply those to `tuple` and `pair`.<br>
</div>
</blockquote>
Maybe, but why do you want to preserve #1?<br></div></blockquote><div><=
br>First, `tuple` doesn't count, as its members are not required to be =
public, nor are they required to be in the appropriate order. So they'r=
e going to have to use its specialized getters no matter what.<br><br>As fo=
r the more general question... I suppose it is not <i>strictly</i> necessar=
y either. So long as <i>all</i> of the NSDMs are publicly accessible (and n=
o virtual inheritance), it could still work.<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
<blockquote type=3D"cite">
<div>=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 bgcolor=3D"#FFFFFF" text=3D"#000000"> I wonder about multiple
inheritance. if <br>
<br>
=C2=A0=C2=A0=C2=A0 struct A: A1, A2 {...};<br>
<br>
Is everyone comfortable with <br>
<br>
=C2=A0=C2=A0=C2=A0 get<0>(a) !=3D
get<0>(static_cast<A2&>(a)<br>
</div>
</blockquote>
<div><br>
Yes. It matches with aggregate initialization in C++17.<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 bgcolor=3D"#FFFFFF" text=3D"#000000"> BTW, what would
get<0>(a) be? static_cast<A1&>(a) or
get<0>(static_cast<A1&>(a))?<br>
</div>
</blockquote>
<div><br>
The same thing it is in aggregate initialization in C++17.<br>
</div>
<br>
</blockquote>
You didn't replayed to my questions?<br></div></blockquote><div><br=
>I didn't? How not? I replied by saying "look at how aggregate ini=
tialization in C++17 works. Make it work like that." That's the an=
swer I'm comfortable with.<br><br>Or let me put it another way. Given t=
his:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, =
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wi=
dth: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #606;" class=3D"styled-by-prettify">=
SomeType</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a=
ggregate </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">val1</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> val2</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> val3</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> val4</span><span 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>this ought to be true (reference types, movemen=
t, etc aside):<br><br><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"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y"><</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">>(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">aggregate</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> val1</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">get</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify"><</span><span style=3D"color: #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">aggregate</s=
pan><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=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> val2</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">aggrega=
te</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> val3</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: #008;" cl=
ass=3D"styled-by-prettify">get</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><</span><span style=3D"color: #066;" class=3D"styled=
-by-prettify">3</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
aggregate</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> val4</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></code></div><=
br>The index aggregate initialization would have used to set the value (eve=
n if it's not, strictly speaking, an aggregate) is exactly the index th=
at tuple-based fetching should retrieve the value. And the same should go f=
or structured binding.<br></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1146_1561077075.1452142972092--
------=_Part_1145_483468076.1452142972091--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 7 Jan 2016 07:58:11 +0100
Raw View
This is a multi-part message in MIME format.
--------------050900000708010704060607
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 07/01/2016 06:02, Nicol Bolas a =C3=A9crit :
> On Wednesday, January 6, 2016 at 4:57:47 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:
>
> Le 06/01/2016 19:40, Nicol Bolas a =C3=A9crit :
>> On Wednesday, January 6, 2016 at 1:13:48 PM UTC-5, Vicente J.
>> Botet Escriba wrote:
>>
>> Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit :
>>> On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J.
>>> Botet Escriba wrote:
>>>
>>> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>>>> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5,
>>>> Matthew Woehlke wrote:
>>>>
>>>> On 2016-01-05 11:00, Nicol Bolas wrote:
>>>> > On 2016-01-04 22:08, Ville Voutilainen wrote:
>>>> >>> The question is why would you check for an
>>>> aggregate?
>>>> >>
>>>> >> The goal is that get<N> would be implicitly
>>>> defined for any "aggregate".
>>>> >> It should *not* be defined however for types
>>>> that have non-public
>>>> >> NSDM's. The question is how to achieve this.
>>>> >>
>>>> >> I should note that one answer is "compiler
>>>> magic". If a standard trait
>>>> >> is going to be a problem, that may be a strong
>>>> argument to use compiler
>>>> >> magic rather than a portable library solution.
>>>> >
>>>> > Well, reflection of any kind, which this whole
>>>> idea relies on, is going to
>>>> > require compiler magic.
>>>>
>>>> True. The question could be better expressed as
>>>> whether the compiler
>>>> magic provides get<N> *directly* (as in, there may
>>>> be no visible
>>>> declaration of the generic form of such), or
>>>> whether get<N> is (visibly,
>>>> in the standard library) implemented with the help
>>>> of traits (which
>>>> themselves are compiler magic, but have broader
>>>> applicability).
>>>>
>>>>
>>>> I say let the whole thing be compiler magic. It'd
>>>> probably be faster to compile that way if the compiler
>>>> can just use intrinsics or whatever to enumerate the
>>>> members of the struct.
>>>>
>>> Thanks to all for your help. Could we conclude then that
>>> the generation should be done when
>>>
>>> - (1) no private or protected non-static data members a=
nd
>>> - (2) no base classes
>>> ?
>>>
>>> Do you see a better characterization?
>>>
>>> We can let the answer to whether it is the compiler that ge=
nerates them or if they are generated using some missing type trait or refl=
ection traits as an open question.
>>>
>>>
>>> I realized while reading your post that the structured
>>> bindings proposal also keys off of being an aggregate when
>>> it is not, strictly speaking, necessary.
>>>
>>> That's when I started to think about what these limitations
>>> exist.
>>>
>>> Aggregate initialization is all about the compiler
>>> generating construction code on the fly. Looked at from that
>>> perspective, the reasoning for the exclusions can be
>>> understood as follows:
>>>
>>> 1) *Types with constructors*: You're not supposed to be able
>>> to initialize a type that has a user-provided constructor
>>> with anything /except/ a call to one of those constructors.
>>> That's how they maintain invariants.
>>> 2) *Public-only members*: Access classes exist so that only
>>> designated code can access that value. So you can't
>>> initialize such values directly; only designated code (ie:
>>> user-provided constructors) may do so.
>>> 3) *Virtual types*: Generating the construction code would
>>> require dealing with filling in virtual stuff. That's more
>>> complex code which would best be expressed with a
>>> constructor. Also, virtual stuff alters the layout of the type.
>>> 4) *Types with base classes*: The layout of base classes is
>>> not well-defined, which makes the initialization code more
>>> complex.
>>>
>>> Notice that C++17 will dispense with #4, presumably because,
>>> well, what does it matter? Yes, the layout is not defined by
>>> the standard, but every class /has/ a layout. The compiler
>>> knows what that layout is, so the compiler can figure out
>>> how to put each item in the aggregate list in the right place.
>>>
>>> When initializing a type, restriction #3 matters, since you
>>> have to fill out the appropriate information. But that
>>> information is irrelevant when /accessing/ NSDMs, either for
>>> these auto-tuplizing functions or for structured binding.
>>>
>>> (note: as I think more on this, it may be problematic with
>>> virtual /inheritance/. But virtual functions themselves
>>> ought to be fine, implementation-wise.)
>>>
>>> So when doing structured binding or tuplized access, we
>>> should only require restrictions #1 and #2 (and possibly no
>>> virtual inheritance).
>> I missed why you want to maintain #1. This will eliminate
>> std::tuple and std::pair :(
>>
>>
>> They already have tuple-like interfaces. And structured binding
>> will already need an extensibility mechanism for types that don't
>> fit this criteria.
>>
>> So just apply those to `tuple` and `pair`.
> Maybe, but why do you want to preserve #1?
>
>
> First, `tuple` doesn't count, as its members are not required to be=20
> public, nor are they required to be in the appropriate order. So=20
> they're going to have to use its specialized getters no matter what.
>
> As for the more general question... I suppose it is not /strictly/=20
> necessary either. So long as /all/ of the NSDMs are publicly=20
> accessible (and no virtual inheritance), it could still work.
>
>> I wonder about multiple inheritance. if
>>
>> struct A: A1, A2 {...};
>>
>> Is everyone comfortable with
>>
>> get<0>(a) !=3D get<0>(static_cast<A2&>(a)
>>
>>
>> Yes. It matches with aggregate initialization in C++17.
>>
>> BTW, what would get<0>(a) be? static_cast<A1&>(a) or
>> get<0>(static_cast<A1&>(a))?
>>
>>
>> The same thing it is in aggregate initialization in C++17.
>>
> You didn't replayed to my questions?
>
>
> I didn't? How not? I replied by saying "look at how aggregate=20
> initialization in C++17 works. Make it work like that." That's the=20
> answer I'm comfortable with.
>
> Or let me put it another way. Given this:
>
> |
> SomeTypeaggregate =3D{val1,val2,val3,val4};
> |
>
> this ought to be true (reference types, movement, etc aside):
>
> |
> get<0>(aggregate)=3D=3Dval1;
> get<1>(aggregate)=3D=3Dval2;
> get<2>(aggregate)=3D=3Dval3;
> get<3>(aggregate)=3D=3Dval4;
> |
>
> The index aggregate initialization would have used to set the value=20
> (even if it's not, strictly speaking, an aggregate) is exactly the=20
> index that tuple-based fetching should retrieve the value. And the=20
> same should go for structured binding.
>
My question was because as I interpret=20
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html=20
from the examples, The aggregation must be nested as in
struct base1 { int b1, b2 =3D 42; };
struct base2 {
B() {
b3 =3D 42;
}
int b3;
};
struct derived : base1, base2 {
int d;
};
derived d1{{1, 2}, {}, 4}; // full initialization
derived d2{{}, {}, 4}; // value-initialized bases
But maybe I'm wrong.
Vicente
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------050900000708010704060607
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 07/01/2016 06:02, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:d29c1908-3f42-4047-8802-6bf2fb4942f0@isocpp.org"
type=3D"cite">On Wednesday, January 6, 2016 at 4:57:47 PM UTC-5,
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;">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/2016 19:40, Nicol Bolas a =C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Wednesday, January 6, 2016 at
1:13:48 PM UTC-5, 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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit=C2=A0:<b=
r>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at
5:08:09 PM UTC-5, 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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit=C2=
=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5,
2016 at 11:38:11 AM UTC-5, Matthew Woehlke
wrote:
<blockquote class=3D"gmail_quote"
style=3D"margin:0;margin-left:0.8ex;border-left:1=
px
#ccc solid;padding-left:1ex">On 2016-01-05
11:00, Nicol Bolas wrote: <br>
> On 2016-01-04 22:08, Ville Voutilainen
wrote: <br>
>>> The question is why would you
check for an aggregate? <br>
>> <br>
>> The goal is that get<N> would
be implicitly defined for any "aggregate". <br>
>> It should *not* be defined however
for types that have non-public <br>
>> NSDM's. The question is how to
achieve this. <br>
>> <br>
>> I should note that one answer is
"compiler magic". If a standard trait <br>
>> is going to be a problem, that may be
a strong argument to use compiler <br>
>> magic rather than a portable library
solution. <br>
> <br>
> Well, reflection of any kind, which this
whole idea relies on, is going to <br>
> require compiler magic. <br>
<br>
True. The question could be better expressed
as whether the compiler <br>
magic provides get<N> *directly* (as in,
there may be no visible <br>
declaration of the generic form of such), or
whether get<N> is (visibly, <br>
in the standard library) implemented with the
help of traits (which <br>
themselves are compiler magic, but have
broader applicability). <br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic.
It'd probably be faster to compile that way if
the compiler can just use intrinsics or
whatever to enumerate the members of the
struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude
then that the generation should be done when<br>
<pre> - (1) no private or protected non-static data=
members and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
</pre>
</div>
</blockquote>
<div>I realized while reading your post that the
structured bindings proposal also keys off of being
an aggregate when it is not, strictly speaking,
necessary.<br>
<br>
That's when I started to think about what these
limitations exist.<br>
<br>
Aggregate initialization is all about the compiler
generating construction code on the fly. Looked at
from that perspective, the reasoning for the
exclusions can be understood as follows:<br>
<br>
1) <b>Types with constructors</b>: You're not
supposed to be able to initialize a type that has a
user-provided constructor with anything <i>except</i>
a call to one of those constructors. That's how they
maintain invariants.<br>
2) <b>Public-only members</b>: Access classes exist
so that only designated code can access that value.
So you can't initialize such values directly; only
designated code (ie: user-provided constructors) may
do so.<br>
3) <b>Virtual types</b>: Generating the
construction code would require dealing with filling
in virtual stuff. That's more complex code which
would best be expressed with a constructor. Also,
virtual stuff alters the layout of the type.<br>
4) <b>Types with base classes</b>: The layout of
base classes is not well-defined, which makes the
initialization code more complex.<br>
<br>
Notice that C++17 will dispense with #4, presumably
because, well, what does it matter? Yes, the layout
is not defined by the standard, but every class <i>has<=
/i>
a layout. The compiler knows what that layout is, so
the compiler can figure out how to put each item in
the aggregate list in the right place.<br>
<br>
When initializing a type, restriction #3 matters,
since you have to fill out the appropriate
information. But that information is irrelevant when
<i>accessing</i> NSDMs, either for these
auto-tuplizing functions or for structured binding.<br>
<br>
(note: as I think more on this, it may be
problematic with virtual <i>inheritance</i>. But
virtual functions themselves ought to be fine,
implementation-wise.)<br>
<br>
So when doing structured binding or tuplized access,
we should only require restrictions #1 and #2 (and
possibly no virtual inheritance).<br>
</div>
</blockquote>
I missed why you want to maintain #1. This will
eliminate std::tuple and std::pair :(<br>
</div>
</blockquote>
<div><br>
They already have tuple-like interfaces. And structured
binding will already need an extensibility mechanism for
types that don't fit this criteria.<br>
<br>
So just apply those to `tuple` and `pair`.<br>
</div>
</blockquote>
Maybe, but why do you want to preserve #1?<br>
</div>
</blockquote>
<div><br>
First, `tuple` doesn't count, as its members are not required to
be public, nor are they required to be in the appropriate order.
So they're going to have to use its specialized getters no
matter what.<br>
<br>
As for the more general question... I suppose it is not <i>strictly=
</i>
necessary either. So long as <i>all</i> of the NSDMs are
publicly accessible (and no virtual inheritance), it could still
work.<br>
</div>
<blockquote class=3D"gmail_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 type=3D"cite">
<div>=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 bgcolor=3D"#FFFFFF" text=3D"#000000"> I wonder about
multiple inheritance. if <br>
<br>
=C2=A0=C2=A0=C2=A0 struct A: A1, A2 {...};<br>
<br>
Is everyone comfortable with <br>
<br>
=C2=A0=C2=A0=C2=A0 get<0>(a) !=3D
get<0>(static_cast<A2&>(a)<br>
</div>
</blockquote>
<div><br>
Yes. It matches with aggregate initialization in C++17.<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 bgcolor=3D"#FFFFFF" text=3D"#000000"> BTW, what would
get<0>(a) be? static_cast<A1&>(a) or
get<0>(static_cast<A1&>(a))?<br>
</div>
</blockquote>
<div><br>
The same thing it is in aggregate initialization in C++17.<br=
>
</div>
<br>
</blockquote>
You didn't replayed to my questions?<br>
</div>
</blockquote>
<div><br>
I didn't? How not? I replied by saying "look at how aggregate
initialization in C++17 works. Make it work like that." That's
the answer I'm comfortable with.<br>
<br>
Or let me put it another way. Given this:<br>
<br>
<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: #606;"
class=3D"styled-by-prettify">SomeType</span><span
style=3D"color: #000;" class=3D"styled-by-prettify">
aggregate </span><span style=3D"color: #660;"
class=3D"styled-by-prettify">=3D</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">val1</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> val2</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> val3</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> val4</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
</span></div>
</code></div>
<br>
this ought to be true (reference types, movement, etc aside):<br>
<br>
<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">get</span><span style=3D"color=
:
#660;" class=3D"styled-by-prettify"><</span><span
style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">aggrega=
te</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=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> val1</=
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">get</span><span style=3D"color=
:
#660;" class=3D"styled-by-prettify"><</span><span
style=3D"color: #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">aggrega=
te</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=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> val2</=
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">get</span><span style=3D"color=
:
#660;" class=3D"styled-by-prettify"><</span><span
style=3D"color: #066;" 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">aggrega=
te</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=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> val3</=
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">get</span><span style=3D"color=
:
#660;" class=3D"styled-by-prettify"><</span><span
style=3D"color: #066;" class=3D"styled-by-prettify">3</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">aggrega=
te</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=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> val4</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
></div>
</code></div>
<br>
The index aggregate initialization would have used to set the
value (even if it's not, strictly speaking, an aggregate) is
exactly the index that tuple-based fetching should retrieve the
value. And the same should go for structured binding.<br>
</div>
<br>
</blockquote>
My question was because as I interpret
<a class=3D"moz-txt-link-freetext" href=3D"http://www.open-std.org/jtc1=
/sc22/wg21/docs/papers/2015/p0017r1.html">http://www.open-std.org/jtc1/sc22=
/wg21/docs/papers/2015/p0017r1.html</a>
from the examples, The aggregation must be nested as in<br>
<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
<pre>struct base1 { int b1, b2 =3D 42; };
struct base2 {=20
B() {
b3 =3D 42;
}
int b3;
};
struct derived : base1, base2 {
int d;
};
derived d1{{1, 2}, {}, 4}; // full initialization
derived d2{{}, {}, 4}; // value-initialized bases
But maybe I'm wrong.
</pre>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------050900000708010704060607--
.
Author: Tom Honermann <Thomas.Honermann@synopsys.com>
Date: Thu, 7 Jan 2016 16:09:21 +0000
Raw View
On 1/6/2016 1:40 PM, Matthew Woehlke wrote:
>> BTW, what would get<0>(a) be? static_cast<A1&>(a) or
>> get<0>(static_cast<A1&>(a))?
>
> The latter, please :-). The latter makes much more sense when
> subclassing is seen as extending the type, which is what is usually done
> when we're talking about aggregates. For example:
>
> struct A { int a; }
> struct B : A { int b; }
>
> ...to access the member A::a from an instance of a B, you write '.a',
> not '.A.a' or some such (usually).
>
> Continuing the example:
>
> struct A { int s, t; }
> struct B : A { int x, y; }
>
> auto x = B{...};
> get<0>(x); // -> A::s
> get<1>(x); // -> A::t
> get<2>(x); // -> B::x
> get<3>(x); // -> B::y
Is it desirable to flatten the structure? My understanding is that
C++17 aggregate initialization doesn't do so. Initializing B requires
braces for the base class:
auto b = B{{0, 1}, 2, 3};
not:
auto b = B{0, 1, 2, 3};
My intuition suggests:
auto x = B{...};
get<0>(x); // -> A subobject
get<0>(get<0>(x)); // -> A::s
get<1>(get<0>*x)); // -> A::t
get<1>(x); // -> B::x
get<2>(x); // -> B::y
Tom.
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 7 Jan 2016 11:24:20 -0800 (PST)
Raw View
------=_Part_7648_334481014.1452194660536
Content-Type: multipart/alternative;
boundary="----=_Part_7649_1447318905.1452194660537"
------=_Part_7649_1447318905.1452194660537
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, January 7, 2016 at 1:58:16 AM UTC-5, Vicente J. Botet Escriba=
=20
wrote:
>
> Le 07/01/2016 06:02, Nicol Bolas a =C3=A9crit :
>
> On Wednesday, January 6, 2016 at 4:57:47 PM UTC-5, Vicente J. Botet=20
> Escriba wrote:=20
>>
>> Le 06/01/2016 19:40, Nicol Bolas a =C3=A9crit :
>>
>> On Wednesday, January 6, 2016 at 1:13:48 PM UTC-5, Vicente J. Botet=20
>> Escriba wrote:=20
>>>
>>> Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit :
>>>
>>> On Tuesday, January 5, 2016 at 5:08:09 PM UTC-5, Vicente J. Botet=20
>>> Escriba wrote:=20
>>>>
>>>> Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit :
>>>>
>>>> On Tuesday, January 5, 2016 at 11:38:11 AM UTC-5, Matthew Woehlke=20
>>>> wrote:=20
>>>>>
>>>>> On 2016-01-05 11:00, Nicol Bolas wrote:=20
>>>>> > On 2016-01-04 22:08, Ville Voutilainen wrote:=20
>>>>> >>> The question is why would you check for an aggregate?=20
>>>>> >>=20
>>>>> >> The goal is that get<N> would be implicitly defined for any=20
>>>>> "aggregate".=20
>>>>> >> It should *not* be defined however for types that have non-public=
=20
>>>>> >> NSDM's. The question is how to achieve this.=20
>>>>> >>=20
>>>>> >> I should note that one answer is "compiler magic". If a standard=
=20
>>>>> trait=20
>>>>> >> is going to be a problem, that may be a strong argument to use=20
>>>>> compiler=20
>>>>> >> magic rather than a portable library solution.=20
>>>>> >=20
>>>>> > Well, reflection of any kind, which this whole idea relies on, is=
=20
>>>>> going to=20
>>>>> > require compiler magic.=20
>>>>>
>>>>> True. The question could be better expressed as whether the compiler=
=20
>>>>> magic provides get<N> *directly* (as in, there may be no visible=20
>>>>> declaration of the generic form of such), or whether get<N> is=20
>>>>> (visibly,=20
>>>>> in the standard library) implemented with the help of traits (which=
=20
>>>>> themselves are compiler magic, but have broader applicability).=20
>>>>>
>>>>
>>>> I say let the whole thing be compiler magic. It'd probably be faster t=
o=20
>>>> compile that way if the compiler can just use intrinsics or whatever t=
o=20
>>>> enumerate the members of the struct.
>>>>
>>>> Thanks to all for your help. Could we conclude then that the generatio=
n=20
>>>> should be done when
>>>>
>>>> - (1) no private or protected non-static data members and
>>>> - (2) no base classes=20
>>>> ?
>>>>
>>>> Do you see a better characterization?
>>>>
>>>> We can let the answer to whether it is the compiler that generates the=
m or if they are generated using some missing type trait or reflection trai=
ts as an open question. =20
>>>>
>>>>
>>>>
>>>> I realized while reading your post that the structured bindings=20
>>> proposal also keys off of being an aggregate when it is not, strictly=
=20
>>> speaking, necessary.
>>>
>>> That's when I started to think about what these limitations exist.
>>>
>>> Aggregate initialization is all about the compiler generating=20
>>> construction code on the fly. Looked at from that perspective, the=20
>>> reasoning for the exclusions can be understood as follows:
>>>
>>> 1) *Types with constructors*: You're not supposed to be able to=20
>>> initialize a type that has a user-provided constructor with anything=20
>>> *except* a call to one of those constructors. That's how they maintain=
=20
>>> invariants.
>>> 2) *Public-only members*: Access classes exist so that only designated=
=20
>>> code can access that value. So you can't initialize such values directl=
y;=20
>>> only designated code (ie: user-provided constructors) may do so.
>>> 3) *Virtual types*: Generating the construction code would require=20
>>> dealing with filling in virtual stuff. That's more complex code which w=
ould=20
>>> best be expressed with a constructor. Also, virtual stuff alters the la=
yout=20
>>> of the type.
>>> 4) *Types with base classes*: The layout of base classes is not=20
>>> well-defined, which makes the initialization code more complex.
>>>
>>> Notice that C++17 will dispense with #4, presumably because, well, what=
=20
>>> does it matter? Yes, the layout is not defined by the standard, but eve=
ry=20
>>> class *has* a layout. The compiler knows what that layout is, so the=20
>>> compiler can figure out how to put each item in the aggregate list in t=
he=20
>>> right place.
>>>
>>> When initializing a type, restriction #3 matters, since you have to fil=
l=20
>>> out the appropriate information. But that information is irrelevant whe=
n=20
>>> *accessing* NSDMs, either for these auto-tuplizing functions or for=20
>>> structured binding.
>>>
>>> (note: as I think more on this, it may be problematic with virtual=20
>>> *inheritance*. But virtual functions themselves ought to be fine,=20
>>> implementation-wise.)
>>>
>>> So when doing structured binding or tuplized access, we should only=20
>>> require restrictions #1 and #2 (and possibly no virtual inheritance).
>>>
>>> I missed why you want to maintain #1. This will eliminate std::tuple an=
d=20
>>> std::pair :(
>>>
>>
>> They already have tuple-like interfaces. And structured binding will=20
>> already need an extensibility mechanism for types that don't fit this=20
>> criteria.
>>
>> So just apply those to `tuple` and `pair`.
>>
>> Maybe, but why do you want to preserve #1?
>>
>
> First, `tuple` doesn't count, as its members are not required to be=20
> public, nor are they required to be in the appropriate order. So they're=
=20
> going to have to use its specialized getters no matter what.
>
> As for the more general question... I suppose it is not *strictly*=20
> necessary either. So long as *all* of the NSDMs are publicly accessible=
=20
> (and no virtual inheritance), it could still work.
>
>> =20
>>
>>> I wonder about multiple inheritance. if=20
>>>
>>> struct A: A1, A2 {...};
>>>
>>> Is everyone comfortable with=20
>>>
>>> get<0>(a) !=3D get<0>(static_cast<A2&>(a)
>>>
>>
>> Yes. It matches with aggregate initialization in C++17.
>> =20
>>
>>> BTW, what would get<0>(a) be? static_cast<A1&>(a) or=20
>>> get<0>(static_cast<A1&>(a))?
>>>
>>
>> The same thing it is in aggregate initialization in C++17.
>>
>> You didn't replayed to my questions?
>>
>
> I didn't? How not? I replied by saying "look at how aggregate=20
> initialization in C++17 works. Make it work like that." That's the answer=
=20
> I'm comfortable with.
>
> Or let me put it another way. Given this:
>
> SomeType aggregate =3D {val1, val2, val3, val4};
>
> this ought to be true (reference types, movement, etc aside):
>
> get<0>(aggregate) =3D=3D val1;
> get<1>(aggregate) =3D=3D val2;
> get<2>(aggregate) =3D=3D val3;
> get<3>(aggregate) =3D=3D val4;
>
> The index aggregate initialization would have used to set the value (even=
=20
> if it's not, strictly speaking, an aggregate) is exactly the index that=
=20
> tuple-based fetching should retrieve the value. And the same should go fo=
r=20
> structured binding.
>
> My question was because as I interpret=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html from=
=20
> the examples, The aggregation must be nested as in
>
> struct base1 { int b1, b2 =3D 42; };
> struct base2 {=20
> B() {
> b3 =3D 42;
> }
> int b3;
> };
> struct derived : base1, base2 {
> int d;
> };
>
> derived d1{{1, 2}, {}, 4}; // full initialization
> derived d2{{}, {}, 4}; // value-initialized bases
>
> But maybe I'm wrong.
>
>
> Vicente
>
No, you're right. I'd forgotten that this is how it works, that base=20
classes are considered member-subobjects.
But my overall point stands: it should work as the exact opposite of=20
aggregate initialization. So in your example, the first index of the tuple=
=20
`A` should be the `A1` base class. The second index should be the `A2` base=
=20
class.
And actually, that brings up a really good reason why we should exclude=20
virtual types of any kind. Because such accesses (particularly structured=
=20
binding) encourages *slicing* of types.
--=20
---=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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_7649_1447318905.1452194660537
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, January 7, 2016 at 1:58:16 AM UTC-5, Vicente J. Botet Escriba =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 07/01/2016 06:02, Nicol Bolas a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Wednesday, January 6, 2016 at 4:57:47 PM U=
TC-5,
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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/2016 19:40, Nicol Bolas a =C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">On Wednesday, January 6, 2016 at
1:13:48 PM UTC-5, 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">
<div bgcolor=3D"#FFFFFF" text=3D"#000000">
<div>Le 06/01/2016 18:49, Nicol Bolas a =C3=A9crit=C2=A0:<b=
r>
</div>
<blockquote type=3D"cite">On Tuesday, January 5, 2016 at
5:08:09 PM UTC-5, Vicente J. Botet Escriba wrote:
<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">
<div>Le 05/01/2016 19:20, Nicol Bolas a =C3=A9crit=C2=
=A0:<br>
</div>
<blockquote type=3D"cite">On Tuesday, January 5,
2016 at 11:38:11 AM UTC-5, Matthew Woehlke
wrote:
<blockquote class=3D"gmail_quote" style=3D"margin:0=
;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 2016-01-=
05
11:00, Nicol Bolas wrote: <br>
> On 2016-01-04 22:08, Ville Voutilainen
wrote: <br>
>>> The question is why would you
check for an aggregate? <br>
>> <br>
>> The goal is that get<N> would
be implicitly defined for any "aggregate&quo=
t;. <br>
>> It should *not* be defined however
for types that have non-public <br>
>> NSDM's. The question is how to
achieve this. <br>
>> <br>
>> I should note that one answer is
"compiler magic". If a standard trait <=
br>
>> is going to be a problem, that may be
a strong argument to use compiler <br>
>> magic rather than a portable library
solution. <br>
> <br>
> Well, reflection of any kind, which this
whole idea relies on, is going to <br>
> require compiler magic. <br>
<br>
True. The question could be better expressed
as whether the compiler <br>
magic provides get<N> *directly* (as in,
there may be no visible <br>
declaration of the generic form of such), or
whether get<N> is (visibly, <br>
in the standard library) implemented with the
help of traits (which <br>
themselves are compiler magic, but have
broader applicability). <br>
</blockquote>
<div><br>
I say let the whole thing be compiler magic.
It'd probably be faster to compile that way i=
f
the compiler can just use intrinsics or
whatever to enumerate the members of the
struct.<br>
</div>
<br>
</blockquote>
Thanks to all for your help. Could we conclude
then that the generation should be done when<br>
<pre> - (1) no private or protected non-static data=
members and
- (2) no base classes=20
?
Do you see a better characterization?
We can let the answer to whether it is the compiler that generates them or =
if they are generated using some missing type trait or reflection traits as=
an open question. =20
</pre>
</div>
</blockquote>
<div>I realized while reading your post that the
structured bindings proposal also keys off of being
an aggregate when it is not, strictly speaking,
necessary.<br>
<br>
That's when I started to think about what these
limitations exist.<br>
<br>
Aggregate initialization is all about the compiler
generating construction code on the fly. Looked at
from that perspective, the reasoning for the
exclusions can be understood as follows:<br>
<br>
1) <b>Types with constructors</b>: You're not
supposed to be able to initialize a type that has a
user-provided constructor with anything <i>except</i>
a call to one of those constructors. That's how the=
y
maintain invariants.<br>
2) <b>Public-only members</b>: Access classes exist
so that only designated code can access that value.
So you can't initialize such values directly; only
designated code (ie: user-provided constructors) may
do so.<br>
3) <b>Virtual types</b>: Generating the
construction code would require dealing with filling
in virtual stuff. That's more complex code which
would best be expressed with a constructor. Also,
virtual stuff alters the layout of the type.<br>
4) <b>Types with base classes</b>: The layout of
base classes is not well-defined, which makes the
initialization code more complex.<br>
<br>
Notice that C++17 will dispense with #4, presumably
because, well, what does it matter? Yes, the layout
is not defined by the standard, but every class <i>has<=
/i>
a layout. The compiler knows what that layout is, so
the compiler can figure out how to put each item in
the aggregate list in the right place.<br>
<br>
When initializing a type, restriction #3 matters,
since you have to fill out the appropriate
information. But that information is irrelevant when
<i>accessing</i> NSDMs, either for these
auto-tuplizing functions or for structured binding.<br>
<br>
(note: as I think more on this, it may be
problematic with virtual <i>inheritance</i>. But
virtual functions themselves ought to be fine,
implementation-wise.)<br>
<br>
So when doing structured binding or tuplized access,
we should only require restrictions #1 and #2 (and
possibly no virtual inheritance).<br>
</div>
</blockquote>
I missed why you want to maintain #1. This will
eliminate std::tuple and std::pair :(<br>
</div>
</blockquote>
<div><br>
They already have tuple-like interfaces. And structured
binding will already need an extensibility mechanism for
types that don't fit this criteria.<br>
<br>
So just apply those to `tuple` and `pair`.<br>
</div>
</blockquote>
Maybe, but why do you want to preserve #1?<br>
</div>
</blockquote>
<div><br>
First, `tuple` doesn't count, as its members are not required t=
o
be public, nor are they required to be in the appropriate order.
So they're going to have to use its specialized getters no
matter what.<br>
<br>
As for the more general question... I suppose it is not <i>strictly=
</i>
necessary either. So long as <i>all</i> of the NSDMs are
publicly accessible (and no virtual inheritance), it could still
work.<br>
</div>
<blockquote class=3D"gmail_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 type=3D"cite">
<div>=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 bgcolor=3D"#FFFFFF" text=3D"#000000"> I wonder about
multiple inheritance. if <br>
<br>
=C2=A0=C2=A0=C2=A0 struct A: A1, A2 {...};<br>
<br>
Is everyone comfortable with <br>
<br>
=C2=A0=C2=A0=C2=A0 get<0>(a) !=3D
get<0>(static_cast<A2&>(a)<br>
</div>
</blockquote>
<div><br>
Yes. It matches with aggregate initialization in C++17.<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 bgcolor=3D"#FFFFFF" text=3D"#000000"> BTW, what would
get<0>(a) be? static_cast<A1&>(a) or
get<0>(static_cast<A1&>(a))?<br>
</div>
</blockquote>
<div><br>
The same thing it is in aggregate initialization in C++17.<br=
>
</div>
<br>
</blockquote>
You didn't replayed to my questions?<br>
</div>
</blockquote>
<div><br>
I didn't? How not? I replied by saying "look at how aggreg=
ate
initialization in C++17 works. Make it work like that." That&#=
39;s
the answer I'm comfortable with.<br>
<br>
Or let me put it another way. Given this:<br>
<br>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code>
<div><span style=3D"color:#606">SomeType</span><span style=3D"c=
olor:#000">
aggregate </span><span style=3D"color:#660">=3D</span><span=
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span styl=
e=3D"color:#000">val1</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> val2</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> val3</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> val4</span><span style=3D"color:#660">};</span><span style=
=3D"color:#000"><br>
</span></div>
</code></div>
<br>
this ought to be true (reference types, movement, etc aside):<br>
<br>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code>
<div><span style=3D"color:#008">get</span><span style=3D"color:=
#660"><</span><span style=3D"color:#066">0</span><span style=3D"color:#6=
60">>(</span><span style=3D"color:#000">aggregate</span><span style=3D"c=
olor:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">=3D=3D</span><span style=3D"color:#000"> val1</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"><br>
</span><span style=3D"color:#008">get</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#066">1</span><span style=3D"colo=
r:#660">>(</span><span style=3D"color:#000">aggregate</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">=3D=3D</span><span style=3D"color:#000"> val2</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br>
</span><span style=3D"color:#008">get</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#066">2</span><span style=3D"colo=
r:#660">>(</span><span style=3D"color:#000">aggregate</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">=3D=3D</span><span style=3D"color:#000"> val3</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br>
</span><span style=3D"color:#008">get</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#066">3</span><span style=3D"colo=
r:#660">>(</span><span style=3D"color:#000">aggregate</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">=3D=3D</span><span style=3D"color:#000"> val4</span><span style=
=3D"color:#660">;</span></div>
</code></div>
<br>
The index aggregate initialization would have used to set the
value (even if it's not, strictly speaking, an aggregate) is
exactly the index that tuple-based fetching should retrieve the
value. And the same should go for structured binding.<br>
</div>
<br>
</blockquote>
My question was because as I interpret
<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p001=
7r1.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D=
9;http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22=
%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0017r1.html\46sa\75D\46sntz\0751\46usg\75=
AFQjCNH_DSMj1V1hhQWrEWCBTE9WR5Ta3Q';return true;" onclick=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%=
2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0017r1.html\46sa\75D\46sntz\0751\46=
usg\75AFQjCNH_DSMj1V1hhQWrEWCBTE9WR5Ta3Q';return true;">http://www.open=
-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2015/<wbr>p0017r1.html</a>
from the examples, The aggregation must be nested as in<br>
<br>
=20
<pre>struct base1 { int b1, b2 =3D 42; };
struct base2 {=20
B() {
b3 =3D 42;
}
int b3;
};
struct derived : base1, base2 {
int d;
};
derived d1{{1, 2}, {}, 4}; // full initialization
derived d2{{}, {}, 4}; // value-initialized bases
But maybe I'm wrong.
</pre>
Vicente<br></div></blockquote><div><br>No, you're right. I'd fo=
rgotten that this is how it works, that base classes are considered member-=
subobjects.<br><br>But my overall point stands: it should work as the exact=
opposite of aggregate initialization. So in your example, the first index =
of the tuple `A` should be the `A1` base class. The second index should be =
the `A2` base class.<br><br>And actually, that brings up a really good reas=
on why we should exclude virtual types of any kind. Because such accesses (=
particularly structured binding) encourages <i>slicing</i> of types.<br></d=
iv>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_7649_1447318905.1452194660537--
------=_Part_7648_334481014.1452194660536--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 12 Jan 2016 12:15:07 -0500
Raw View
On 2016-01-07 14:24, Nicol Bolas wrote:
> On Thursday, January 7, 2016 at 1:58:16 AM UTC-5, Vicente J. Botet Escriba
> wrote:
>> My question was because as I interpret
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0017r1.html from
>> the examples, The aggregation must be nested as in
>>
>> struct base1 { int b1, b2 = 42; };
>> struct base2 {
>> B() {
>> b3 = 42;
>> }
>> int b3;
>> };
>> struct derived : base1, base2 {
>> int d;
>> };
>>
>> derived d1{{1, 2}, {}, 4}; // full initialization
>> derived d2{{}, {}, 4}; // value-initialized bases
>>
>> But maybe I'm wrong.
>
> No, you're right. I'd forgotten that this is how it works, that base
> classes are considered member-subobjects.
Likewise. It... feels strange to me, but I guess it is what it is.
> But my overall point stands: it should work as the exact opposite of
> aggregate initialization. So in your example, the first index of the tuple
> `A` should be the `A1` base class. The second index should be the `A2` base
> class.
Agreed.
> And actually, that brings up a really good reason why we should exclude
> virtual types of any kind. Because such accesses (particularly structured
> binding) encourages *slicing* of types.
Yup :-).
--
Matthew
--
---
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.