220 23585 <c81edceb-0ea1-46e8-ba26-024586f64a1a@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: n4428 and Tuple-like access interface reflection
Date: Thu, 7 Jan 2016 11:24:20 -0800 (PST)
Lines: 610
Approved: news@gmane.org
Message-ID: <c81edceb-0ea1-46e8-ba26-024586f64a1a@isocpp.org>
References: <56770133.7070701@wanadoo.fr> <5681D877.3010101@wanadoo.fr>
 <43daa6cd-e152-43c1-ab51-0661779d344b@isocpp.org>
 <n5ug1h$fgg$1@ger.gmane.org>
 <CAB+4KH+bBEwFidv=a5wuOLbyBtSTwy0TKB=r_7Mc_8vx_bRrPA@mail.gmail.com>
 <n60u6u$7ov$1@ger.gmane.org> <568942A9.80700@wanadoo.fr>
 <n6e4n4$q68$1@ger.gmane.org> <568B0DA1.3080704@wanadoo.fr>
 <b98e9903-52b2-41b4-ac89-8c3e8df4d9c1@isocpp.org>
 <n6gnfr$57q$1@ger.gmane.org>
 <7d4bd204-e4c3-4f60-8be5-63d8127daf74@isocpp.org>
 <n6grh7$b8q$1@ger.gmane.org>
 <487ea013-6fcb-4d2e-8bc7-8fe96cdbf0a9@isocpp.org>
 <568C3EC7.8070900@wanadoo.fr>
 <a6ad88f3-2309-499a-aeca-834ecb0dfd0d@isocpp.org>
 <568D5959.9000501@wanadoo.fr>
 <c087a17d-6ab0-40d3-acd7-e7c364edd388@isocpp.org> <568D8DD7.30303@wanadoo.fr>
 <d29c1908-3f42-4047-8802-6bf2fb4942f0@isocpp.org>
 <568E0C83.7030609@wanadoo.fr>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_7648_334481014.1452194660536"
X-Trace: ger.gmane.org 1452194682 3027 80.91.229.3 (7 Jan 2016 19:24:42 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Thu, 7 Jan 2016 19:24:42 +0000 (UTC)
Cc: mwoehlke.floss@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBZXWXK2AKGQE4ZVNUTI@isocpp.org Thu Jan 07 20:24:26 2016
Return-path: <std-proposals+bncBCEKFTV6ZUMBBZXWXK2AKGQE4ZVNUTI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-io0-f198.google.com ([209.85.223.198])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBZXWXK2AKGQE4ZVNUTI@isocpp.org>)
	id 1aHGAZ-0001Zo-Ly
	for gclcip-std-proposals@m.gmane.org; Thu, 07 Jan 2016 20:24:24 +0100
Original-Received: by mail-io0-f198.google.com with SMTP id s102sf117033141ioi.0
        for <gclcip-std-proposals@m.gmane.org>; Thu, 07 Jan 2016 11:24:23 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:content-type:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=8TIChtyzrhbrzjSeamv3Wy/KlyOxlGhTOr6oK5+bmL0=;
        b=V0gU5vC7PIkg1TLKmheY157hiabMUIW5tUT4ZytO1OmyCrNfJ2QtunoOxOkJWCGygA
         t2L788wsESDNqlspbeIPBTkiaPG2C9q6BhSNyGp6/Wa5ZXs8PHwGlvluqWQ845kjaomq
         b0XunVHlf+AEiQmAB8/EHROIElB7wp5G4uFTTO109U7y60QpDfUQKFdeBgTAIkZe1CCb
         azwNE2kaM3NEzcf1hxeWyoHb54q1sIArPH1Yi62rpOWLDPkgTUF1ywpHKltB9lPEcfLp
         7nTnL1G7UaZRlbNEULiLyarKqENYpA2R+J2JMNUWI6LVC/b/opIMKAQr+fDBlXfF6AbA
         Q7yA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:content-type:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=8TIChtyzrhbrzjSeamv3Wy/KlyOxlGhTOr6oK5+bmL0=;
        b=XNkPa3Da1h8GVbeWetWwyQs72+sOlCHlKM8vkTyhhrhOF7a/WftRPSDS0MdpnmtxwE
         EBFsm2YV4on/MhVIVP4rbIX+h+XSZ/dTHqzGMnkjDGltGfpLdiG4a52e5FiSeQO6hnYR
         7VsectEPd/BipisjG81eXK84gKu7En3rc7yz9EJa//HRrAZQuJlgeLJZRvPz9zmcrMZz
         psiUrkApNV9tur/Awtq2rvTuJWUeK5+4tiQO8phYpwd6et3IlJNI90iAnpr2W0LMlZ6W
         iBTwJq+r7lytgdBozVQPHxqD0XAPPpq8y/hPkpkzlBvAA6BFf1vvPrkBpsms/CxTzTiv
         H6HQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:content-type:x-original-sender
         :reply-to:precedence:mailing-list:list-id:x-spam-checked-in-group
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=8TIChtyzrhbrzjSeamv3Wy/KlyOxlGhTOr6oK5+bmL0=;
        b=jqaCi5YCza7HnElSFERWgRszzFlisnbAboE3INip3Unsq21wn29RcF2D4e5MNIcjCd
         2aPa3fvThu2UOAbd+SXJc6D8rYPn9Z0lbzC8dGxy5pi5Cvuh5mvNKMp8QI4k99JhHhPb
         fSSLzNbYve9eXGOa8JSHgmi7EHYcPSWzggPbZrKLrsG5WmbIHuFfZ/YQbdSVAzhqwmAf
         w3psZ7P+JaUJet35WcJssbcRyoHj/ct9o4h7x//GxIFuAgDChtL+jXsI4qB/vVQlunRv
         iruoubVkuoMOvcpqaIGL364rLeFVoFH6mQUTML+f8VZOMX7HncJZ5Oip72+uFxNVgu74
         pgig==
X-Gm-Message-State: ALoCoQlRHeYuXRA20iYQoHqgCYBoaxs/fy11phS/pabwJo4522ji1pBSvKD/QxKXPMNa7mp5Jmns5tTwh3qDCs7fbNt6zMpWQg==
X-Received: by 10.50.70.42 with SMTP id j10mr15397146igu.9.1452194662646;
        Thu, 07 Jan 2016 11:24:22 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.50.102.3 with SMTP id fk3ls924100igb.1.canary; Thu, 07 Jan
 2016 11:24:21 -0800 (PST)
X-Received: by 10.50.57.84 with SMTP id g20mr551334igq.3.1452194661815;
        Thu, 07 Jan 2016 11:24:21 -0800 (PST)
In-Reply-To: <568E0C83.7030609@wanadoo.fr>
X-Original-Sender: jmckesson@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:23585
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/23585>

------=_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>
                          &gt; On 2016-01-04 22:08, Ville Voutilainen
                          wrote: <br>
                          &gt;&gt;&gt; The question is why would you
                          check for an aggregate? <br>
                          &gt;&gt; <br>
                          &gt;&gt; The goal is that get&lt;N&gt; would
                          be implicitly defined for any &quot;aggregate&quo=
t;. <br>
                          &gt;&gt; It should *not* be defined however
                          for types that have non-public <br>
                          &gt;&gt; NSDM&#39;s. The question is how to
                          achieve this. <br>
                          &gt;&gt; <br>
                          &gt;&gt; I should note that one answer is
                          &quot;compiler magic&quot;. If a standard trait <=
br>
                          &gt;&gt; is going to be a problem, that may be
                          a strong argument to use compiler <br>
                          &gt;&gt; magic rather than a portable library
                          solution. <br>
                          &gt; <br>
                          &gt; Well, reflection of any kind, which this
                          whole idea relies on, is going to <br>
                          &gt; require compiler magic. <br>
                          <br>
                          True. The question could be better expressed
                          as whether the compiler <br>
                          magic provides get&lt;N&gt; *directly* (as in,
                          there may be no visible <br>
                          declaration of the generic form of such), or
                          whether get&lt;N&gt; 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&#39;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&#39;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&#39;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&#39;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&#39;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&#39;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&#39;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&#39;t count, as its members are not required t=
o
        be public, nor are they required to be in the appropriate order.
        So they&#39;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&lt;0&gt;(a) !=3D
                get&lt;0&gt;(static_cast&lt;A2&amp;&gt;(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&lt;0&gt;(a) be? static_cast&lt;A1&amp;&gt;(a) or
                get&lt;0&gt;(static_cast&lt;A1&amp;&gt;(a))?<br>
              </div>
            </blockquote>
            <div><br>
              The same thing it is in aggregate initialization in C++17.<br=
>
            </div>
            <br>
          </blockquote>
          You didn&#39;t replayed to my questions?<br>
        </div>
      </blockquote>
      <div><br>
        I didn&#39;t? How not? I replied by saying &quot;look at how aggreg=
ate
        initialization in C++17 works. Make it work like that.&quot; That&#=
39;s
        the answer I&#39;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">&lt;</span><span style=3D"color:#066">0</span><span style=3D"color:#6=
60">&gt;(</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">&lt;</span><span style=3D"color:#066">1</span><span style=3D"colo=
r:#660">&gt;(</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">&lt;</span><span style=3D"color:#066">2</span><span style=3D"colo=
r:#660">&gt;(</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">&lt;</span><span style=3D"color:#066">3</span><span style=3D"colo=
r:#660">&gt;(</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&#39;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&#3=
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&#39;;return true;" onclick=3D"this.href=
=3D&#39;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&#39;;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&#39;m wrong.

</pre>
    Vicente<br></div></blockquote><div><br>No, you&#39;re right. I&#39;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&quot; 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--

.
