220 36101 <3ec0bd22-b228-4026-bb49-aec5102918c7@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Sub-objects and their copy ellision
Date: Tue, 19 Dec 2017 17:06:36 -0800 (PST)
Lines: 322
Approved: news@gmane.org
Message-ID: <3ec0bd22-b228-4026-bb49-aec5102918c7@isocpp.org>
References: <caca241d-3498-b79b-fbf3-e57d8b7c3518@technion.ac.il>
 <1c6eff77-d71f-4dd7-8c13-f609460a03f0@isocpp.org>
 <c14fe13b-a658-e295-40a6-1465638d18db@technion.ac.il>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_775_113262069.1513731997094"
X-Trace: blaine.gmane.org 1513731882 31523 195.159.176.226 (20 Dec 2017 01:04:42 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Wed, 20 Dec 2017 01:04:42 +0000 (UTC)
Cc: jmckesson@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBHPP43IQKGQEUYVRRWI@isocpp.org Wed Dec 20 02:04:38 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBBHPP43IQKGQEUYVRRWI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f71.google.com ([209.85.213.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBHPP43IQKGQEUYVRRWI@isocpp.org>)
	id 1eRSoH-0007ks-5j
	for gclcip-std-proposals@m.gmane.org; Wed, 20 Dec 2017 02:04:37 +0100
Original-Received: by mail-vk0-f71.google.com with SMTP id w64sf1024181vkd.12
        for <gclcip-std-proposals@m.gmane.org>; Tue, 19 Dec 2017 17:06:39 -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:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=PoCf+EqEIxv7nFMpJbP6fyU1ogOpGfDpdkusjFm/gi0=;
        b=yCCgVlvzfsdbVzbTexPKehcqGfjI6ppLWoL5kVWQxnPC+2mueqb03C3pOJZqmvrnMO
         gzpspZr79jn0SPN5Z+EVHtfIFcL0WkJ7sHsp19fyb91MBYOx/+IjBmEYdM/nHriroPPM
         tFAIQbTHgth5I1UnAxo5aXKFbQqVnti/0CKmmIQc7Zwiyfvi7YzLXskd3/CPqcYMfjKr
         w053iWL+IVYcPM6tzpwcv66UAGc29CCRWl8DC0z3EtTtg+oldYwggJzLt3i/v178WuQn
         iFm3IrGI1pwZgV1SQUCbtyOsi80BOovr5Zx0UegsdZr1tGYciYYR/UW2opYPG33vHI4q
         dZ2A==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=PoCf+EqEIxv7nFMpJbP6fyU1ogOpGfDpdkusjFm/gi0=;
        b=d2sBDx9B5vB222yfz0elxs4l5zb+KK5rWcEEN2j+8d6dNQ4lLU2dwlMAM8JWm4GW2x
         38i8Ipi12B1Zt9hECLEXL4SLHo0ewf8fAz400hOcTu/y0PoaZeD/8rtpFGtyEGVQskz/
         gH5JR8ufe6sxchGqY6vgLYh71QLgZ91OD+/h7VDIRXK6hrymoWiCi7OrKQa3iMLEUGKS
         T0Qjy2x6w4h78vm8w0WWcby9iBPVQ3Pk5cRFO8Z2UPm7seB3F7suQMvINMqEwZ6IKFmA
         GNwhy893eX8ENpf9C+3GaiGkGUxoQ2LBFrQV3AidNj5/ZoF3OgsRhhAoaM/AHbekhH76
         7wdA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version: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=PoCf+EqEIxv7nFMpJbP6fyU1ogOpGfDpdkusjFm/gi0=;
        b=UfNRH2/zhKeIarjQzXzeecT4J6KMmi2sQUfbzT9cxBLNxW9GT+OaKtw2hW39QVXD96
         2gw72Y9pOQ5t2VVd3EXVmvncdJwW0Ny1I8nvZlVCJMeCPC7EY/xqe1QPx2LJc1zdffXg
         YrjbhLbyu+RfhDZ2K8lmY6eljGnQ1th6za3LzdVULU0Wj7rp0YgVLZAm8jcKwJ44kbLU
         3+KeAfenTSjTLynFRIgNi/v1YcwTyXmKl7xRH8WC/snXlSeNc305jRKx2aD9V+6XM8D2
         QyGGQV79XHgqvUXPQpdjCcJuVd6rff/NOhFRDRC9bFZJi/ZRWuYrTbik21tm+kCXhoE4
         PQgw==
X-Gm-Message-State: AKGB3mLt2aNV3J7Z2Ljm7jDe8IlrU9TwOSSWZF7OE99OxjxUbgmv7LOD
	Yb2Z3S2IY6QfgroegGZmiuUo8Q==
X-Google-Smtp-Source: ACJfBosJ8jMBnV1+pgDSlOzgev/Z+LpEWyTvu6w0Apf1p6Qy0wIF7KjnZM8CIMoyQmYoThVJkPFKSw==
X-Received: by 10.176.112.57 with SMTP id u25mr2638155ual.85.1513731999200;
        Tue, 19 Dec 2017 17:06:39 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.87.70 with SMTP id l67ls5498542vkb.6.gmail; Tue, 19 Dec
 2017 17:06:37 -0800 (PST)
X-Received: by 10.31.48.213 with SMTP id w204mr495042vkw.12.1513731997667;
        Tue, 19 Dec 2017 17:06:37 -0800 (PST)
In-Reply-To: <c14fe13b-a658-e295-40a6-1465638d18db@technion.ac.il>
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:36101
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36101>

------=_Part_775_113262069.1513731997094
Content-Type: multipart/alternative; 
	boundary="----=_Part_776_1421323396.1513731997094"

------=_Part_776_1421323396.1513731997094
Content-Type: text/plain; charset="UTF-8"



On Tuesday, December 19, 2017 at 5:09:34 PM UTC-5, Eyal Rozenberg wrote:
>
>
>
> On 12/19/17 9:10 PM, Nicol Bolas wrote: 
> > look at what [class.copy.elision]/1.1 says: 
> > 
> >> when the expression is the name of a non-volatile automatic object 
> > (other than a function parameter or a variable introduced by the 
> > exception-declaration of a handler (18.3)) 
> > 
> > The expression `v.first` is not "the name of a non-volatile automatic 
> > object". `first` is not an automatic object; it is a member subobject of 
> > `v`. And `v.first` is not its name; `first` is its name. `v.first` is an 
> > expression that accesses a subobject from an object. 
>
> Ah. Indeed, it seems only variables can have "automatic storage 
> duration", even though their sub-objects have the same storage behavior 
> as them. Ok. 
>
> > Now, consider this: 
> > 
> > | 
> > stringfoo() 
> > { 
> >   pair<string,string>pr; 
> >   pr.first =...; 
> >   returnpr.first; 
> > } 
> > | 
> > 
> > The layout of `pair<string, string>` is fixed. 
>
> But when optimizing, the compiler is not committed to using that layout.
>

Yes, it is. I can pass a pointer/reference to `pr` to any function, and 
that function has to be able to work with what I generate.

In fact, in the example you've given it can completely drop pr, and just 
> construct the returned string at the area where a string is supposed to 
> end up. It will be "as if" the pr was used and the first element was 
> copied. 
>
> > But the/caller/ doesn't know that. The caller is the one who provides 
> > memory for the return value object. And as far as the caller can tell, 
> > all it needs to provide is `sizeof(string)` bytes. 
>
> ... which is good enough with your specific example. Now, it's true that 
> there could be code in foo() which depends on the layout being as it is 
> that a compiler's optimizer will not be able to clear away; but there 
> could also not be such code. And since, like you pointed out at the 
> beginning of your reply, elision is just an option - why not give that 
> option?
>
 
What "option"?

Just within this thread, we have identified a number of limitations on what 
you can do with such objects. Let's not go further than merely what you've 
already agree to: destruction of subobjects and layout. That is, this 
optimization is not possible if any of the following is true:

1) The containing type has a non-defaulted destructor.
2) The containing object is not passed to another function by pointer or 
reference, since that requires the object's layout to be consistent with 
what the standard says.
3) The user of the containing object does not do anything layout-specific 
itself.

Note that this is almost certainly* not* a complete list. It's merely the 
ones talked about thus far; there are almost certainly others.

Item #2 is particularly important. Why? Because that rules out calling* any 
member functions*, since all non-static member functions take the object by 
pointer. And that requires the object's layout to be consistent with its 
definition.

Notice that "Motivating example #2" doesn't qualify for this, since we call 
a function on the object. That requires it to have a certain layout.

So, how much real code actually qualifies for such elision?

Because here's the thing the person behind that proposal just doesn't get. 
His proposal* doesn't work*. It does not solve the problem. Why?

Because compilers can't do it in so many of these cases. RVO was very 
reliable; when compilers offered it, it worked for any case of returning a 
prvalue. NRVO is pretty reliable; declare the variable at the top of the 
function, return it whenever, and you're almost guaranteed to get the 
optimization.

What are the guidelines for getting this proposal's optimizations? What 
circumstances stop it, and what can be done to avoid them?

Because here's the thing: if I do this:

string foo()
{
  string str;
  str = ...;
  return str;
}

If I do that, and I* don't* get elision, it's still fine. Why? Because I 
still get automatic move support. `str` in the return statement is a 
reference to an automatic variable in the function's scope, so it is moved 
from. I may not have gotten the best answer, but I got a good enough one.

In this case:

string foo()
{
  pair<string, string> pr = ...;
  return pr.second;
}

What happens if this doesn't get elided? Well, you get a copy. The only way 
to get a move is to ask for it: `return std::move(pr.second)`.

So the proposal actually* encourages bad code*, on the assumption that the 
compiler will swoop in and save you.

-- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3ec0bd22-b228-4026-bb49-aec5102918c7%40isocpp.org.

------=_Part_776_1421323396.1513731997094
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, December 19, 2017 at 5:09:34 PM UTC-5,=
 Eyal Rozenberg wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>
<br>On 12/19/17 9:10 PM, Nicol Bolas wrote:
<br>&gt; look at what [class.copy.elision]/1.1 says:
<br>&gt;=20
<br>&gt;&gt; when the expression is the name of a non-volatile automatic ob=
ject
<br>&gt; (other than a function parameter or a variable introduced by the
<br>&gt; exception-declaration of a handler (18.3))
<br>&gt;=20
<br>&gt; The expression `v.first` is not &quot;the name of a non-volatile a=
utomatic
<br>&gt; object&quot;. `first` is not an automatic object; it is a member s=
ubobject of
<br>&gt; `v`. And `v.first` is not its name; `first` is its name. `v.first`=
 is an
<br>&gt; expression that accesses a subobject from an object.
<br>
<br>Ah. Indeed, it seems only variables can have &quot;automatic storage
<br>duration&quot;, even though their sub-objects have the same storage beh=
avior
<br>as them. Ok.
<br>
<br>&gt; Now, consider this:
<br>&gt;=20
<br>&gt; |
<br>&gt; stringfoo()
<br>&gt; {
<br>&gt; =C2=A0 pair&lt;string,string&gt;pr;
<br>&gt; =C2=A0 pr.first =3D...;
<br>&gt; =C2=A0 returnpr.first;
<br>&gt; }
<br>&gt; |
<br>&gt;=20
<br>&gt; The layout of `pair&lt;string, string&gt;` is fixed.
<br>
<br>But when optimizing, the compiler is not committed to using that layout=
..<br></blockquote><div><br></div><div>Yes, it is. I can pass a pointer/refe=
rence to `pr` to any function, and that function has to be able to work wit=
h what I generate.</div><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;">In fact, in the example you&#39;ve given it can completely drop pr=
, and just
<br>construct the returned string at the area where a string is supposed to
<br>end up. It will be &quot;as if&quot; the pr was used and the first elem=
ent was copied.
<br>
<br>&gt; But the/caller/ doesn&#39;t know that. The caller is the one who p=
rovides
<br>&gt; memory for the return value object. And as far as the caller can t=
ell,
<br>&gt; all it needs to provide is `sizeof(string)` bytes.
<br>
<br>... which is good enough with your specific example. Now, it&#39;s true=
 that
<br>there could be code in foo() which depends on the layout being as it is
<br>that a compiler&#39;s optimizer will not be able to clear away; but the=
re
<br>could also not be such code. And since, like you pointed out at the
<br>beginning of your reply, elision is just an option - why not give that
<br>option?<br></blockquote><div>=C2=A0</div><div>What &quot;option&quot;?<=
/div><div><br></div><div>Just within this thread, we have identified a numb=
er of limitations on what you can do with such objects. Let&#39;s not go fu=
rther than merely what you&#39;ve already agree to: destruction of subobjec=
ts and layout. That is, this optimization is not possible if any of the fol=
lowing is true:</div><div><br></div><div>1) The containing type has a non-d=
efaulted destructor.</div><div>2) The containing object is not passed to an=
other function by pointer or reference, since that requires the object&#39;=
s layout to be consistent with what the standard says.</div><div>3) The use=
r of the containing object does not do anything layout-specific itself.</di=
v><div><br></div><div>Note that this is almost certainly<i> not</i> a compl=
ete list. It&#39;s merely the ones talked about thus far; there are almost =
certainly others.</div><div><i><br></i></div><div>Item #2 is particularly i=
mportant. Why? Because that rules out calling<i> any member functions</i>, =
since all non-static member functions take the object by pointer. And that =
requires the object&#39;s layout to be consistent with its definition.</div=
><div><br></div><div>Notice that &quot;<span style=3D"display: inline !impo=
rtant; float: none; background-color: transparent; color: rgb(34, 34, 34); =
font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size:=
 13px; font-style: normal; font-variant: normal; font-weight: 400; letter-s=
pacing: normal; orphans: 2; text-align: left; text-decoration: none; text-i=
ndent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-spa=
ce: normal; word-spacing: 0px;">Motivating example #2&quot; doesn&#39;t qua=
lify for this, since we call a function on the object. That requires it to =
have a certain layout.</span></div><div><span style=3D"display: inline !imp=
ortant; float: none; background-color: transparent; color: rgb(34, 34, 34);=
 font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size=
: 13px; font-style: normal; font-variant: normal; font-weight: 400; letter-=
spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-=
indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-sp=
ace: normal; word-spacing: 0px;"><br></span></div><div>So, how much real co=
de actually qualifies for such elision?</div><div><br></div><div>Because he=
re&#39;s the thing the person behind that proposal just doesn&#39;t get. Hi=
s proposal<i> doesn&#39;t work</i>. It does not solve the problem. Why?</di=
v><div><br></div><div>Because compilers can&#39;t do it in so many of these=
 cases. RVO was very reliable; when compilers offered it, it worked for any=
 case of returning a prvalue. NRVO is pretty reliable; declare the variable=
 at the top of the function, return it whenever, and you&#39;re almost guar=
anteed to get the optimization.</div><div><br></div><div>What are the guide=
lines for getting this proposal&#39;s optimizations? What circumstances sto=
p it, and what can be done to avoid them?</div><div><br></div><div>Because =
here&#39;s the thing: if I do this:</div><div><br></div><div class=3D"prett=
yprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-wor=
d; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color:=
 #008;">string</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"> foo</span><span class=3D"styled-by-prettify" style=3D"color: #660;">()=
</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span=
><span class=3D"styled-by-prettify" style=3D"color: #660;">{</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 </span><span c=
lass=3D"styled-by-prettify" style=3D"color: #008;">string</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> str</span><span class=3D"st=
yled-by-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"><br>=C2=A0 str </span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">=3D</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">...;</span><span class=3D"styled-by-prettify" style=3D=
"color: #000;"><br>=C2=A0 </span><span class=3D"styled-by-prettify" style=
=3D"color: #008;">return</span><span class=3D"styled-by-prettify" style=3D"=
color: #000;"> str</span><span class=3D"styled-by-prettify" style=3D"color:=
 #660;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><=
br></span><span class=3D"styled-by-prettify" style=3D"color: #660;">}</span=
></div></code></div><div><br></div><div>If I do that, and I<i> don&#39;t</i=
> get elision, it&#39;s still fine. Why? Because I still get automatic move=
 support. `str` in the return statement is a reference to an automatic vari=
able in the function&#39;s scope, so it is moved from. I may not have gotte=
n the best answer, but I got a good enough one.</div><div><br></div><div>In=
 this case:</div><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 class=3D"styled-by-prettify" style=3D"color: #008;">string</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #000;"> foo</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #660;">()</span><span class=3D"st=
yled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"styled-b=
y-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by-prettif=
y" style=3D"color: #000;"><br>=C2=A0 pair</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-prettify=
" style=3D"color: #008;">string</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #008=
;">string</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&=
gt;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> pr </s=
pan><span class=3D"styled-by-prettify" style=3D"color: #660;">=3D</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">...;</span><span class=3D"st=
yled-by-prettify" style=3D"color: #000;"><br>=C2=A0 </span><span class=3D"s=
tyled-by-prettify" style=3D"color: #008;">return</span><span class=3D"style=
d-by-prettify" style=3D"color: #000;"> pr</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #660;">.</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #000;">second</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">}</span></div></code></div><div><br></div><div>What happens if this does=
n&#39;t get elided? Well, you get a copy. The only way to get a move is to =
ask for it: `return std::move(pr.second)`.</div><div><br></div><div>So the =
proposal actually<i> encourages bad code</i>, on the assumption that the co=
mpiler will swoop in and save you.<br></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3ec0bd22-b228-4026-bb49-aec5102918c7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3ec0bd22-b228-4026-bb49-aec5102918c7=
%40isocpp.org</a>.<br />

------=_Part_776_1421323396.1513731997094--

------=_Part_775_113262069.1513731997094--

.
