220 16324 <CAD6_Qj8SS1cEtnRgcKXx2-F35151w=VhRnjaGwooJrQCVSyngg@mail.gmail.com> article
Path: news.gmane.org!not-for-mail
From: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Pointers to members of unknown class
Date: Tue, 17 Feb 2015 08:48:22 -0500
Lines: 324
Approved: news@gmane.org
Message-ID: <CAD6_Qj8SS1cEtnRgcKXx2-F35151w=VhRnjaGwooJrQCVSyngg@mail.gmail.com>
References: <9b03a820-0ac5-4931-9825-b2fc9ef893f9@isocpp.org>
	<885c1fbd-8701-4f70-b7ad-89ee9104f42d@isocpp.org>
	<b9e49990-712d-412e-9789-6aa83f22c0de@isocpp.org>
	<e33b4000-bcf7-4040-952e-b0a5e81edd60@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=001a11354faad22f0a050f48f42f
X-Trace: ger.gmane.org 1424180914 14936 80.91.229.3 (17 Feb 2015 13:48:34 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Tue, 17 Feb 2015 13:48:34 +0000 (UTC)
To: "std-proposals@isocpp.org" <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDIIVO6GQULBBJ4NRWTQKGQE3ZGWMOI@isocpp.org Tue Feb 17 14:48:34 2015
Return-path: <std-proposals+bncBDIIVO6GQULBBJ4NRWTQKGQE3ZGWMOI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pa0-f72.google.com ([209.85.220.72])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDIIVO6GQULBBJ4NRWTQKGQE3ZGWMOI@isocpp.org>)
	id 1YNiVq-0005vJ-CF
	for gclcip-std-proposals@m.gmane.org; Tue, 17 Feb 2015 14:48:30 +0100
Original-Received: by pabrd3 with SMTP id rd3sf37004174pab.1
        for <gclcip-std-proposals@m.gmane.org>; Tue, 17 Feb 2015 05:48:24 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:sender:in-reply-to:references:date
         :message-id:subject:from:to:content-type:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=uDCLhLUyo8u+mPjcgCowxkVuCtaTIqt2Uu+dUtzFaNw=;
        b=WRRh2emT2D76Uw22Wix7IyL03uyqE3KNHveJL/IvbvSYzmJXSB6V2ZEK/LyO7I1441
         5O9f48z/Ji1xOJ1UeEhnQ1P7TNPqxXAssHFbXX4noThylSrgm9HjRqnFTSNY59oxV0QI
         s9SWZIT1njTUDL/BMcQZF3g7zm7h320mYjboqSL7TJRCh3X6vDPFJ8ExaNr4JcV61w3U
         1kJOT7DjwGExPDNK+sHoNshFWMP/J19qSbQo+lx4jGFlpVI5aBpHppRoFzpwh2WJJlgg
         IcSdnaENgl0SVpzCaBPGOMshBcQxA5uUbza2j24+9om3+NStlQ1IukHX9k1vDDGmCBya
         Gx/w==
X-Gm-Message-State: ALoCoQkjc5imA6RFidQ5ayBiwf1lamqGr0A7deF99/J6RgDqDtYRKdz7V+++14U8S8JpRwpUU5AJ
X-Received: by 10.66.224.42 with SMTP id qz10mr25734004pac.0.1424180904448;
        Tue, 17 Feb 2015 05:48:24 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.140.22.84 with SMTP id 78ls751769qgm.39.gmail; Tue, 17 Feb
 2015 05:48:23 -0800 (PST)
X-Received: by 10.140.135.200 with SMTP id 191mr1077632qhh.25.1424180903459;
        Tue, 17 Feb 2015 05:48:23 -0800 (PST)
Original-Received: from mail-qg0-x234.google.com (mail-qg0-x234.google.com. [2607:f8b0:400d:c04::234])
        by mx.google.com with ESMTPS id p32si17779299qgd.45.2015.02.17.05.48.23
        for <std-proposals@isocpp.org>
        (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Tue, 17 Feb 2015 05:48:23 -0800 (PST)
Received-SPF: pass (google.com: domain of dribeas@gmail.com designates 2607:f8b0:400d:c04::234 as permitted sender) client-ip=2607:f8b0:400d:c04::234;
Original-Received: by mail-qg0-f52.google.com with SMTP id h3so27850697qgf.11
        for <std-proposals@isocpp.org>; Tue, 17 Feb 2015 05:48:23 -0800 (PST)
X-Received: by 10.140.232.149 with SMTP id d143mr620009qhc.82.1424180903028;
 Tue, 17 Feb 2015 05:48:23 -0800 (PST)
Original-Sender: dribeas@gmail.com
Original-Received: by 10.140.104.207 with HTTP; Tue, 17 Feb 2015 05:48:22 -0800 (PST)
In-Reply-To: <e33b4000-bcf7-4040-952e-b0a5e81edd60@isocpp.org>
X-Original-Sender: dibeas@ieee.org
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of dribeas@gmail.com designates 2607:f8b0:400d:c04::234 as permitted
 sender) smtp.mail=dribeas@gmail.com;       dkim=pass header.i=@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://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>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:16324
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/16324>

--001a11354faad22f0a050f48f42f
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Sorry for looking like the bad guy here, but I am still unsure of the
feature. Little added value and increased dangers as people don't quite
understand pointers to members.

To be clear, the Itanium ABI does not have the pointer-to-member sizes
described in the document to adhere to the requirement of
'reinterpret_cast', but rather as the result of the design of dynamic
dispatch in that ABI (what value is 'this' on entry to the final
overrider?).

I am fine changing the standard to make VS implementation conformant. For
that a single change needs to be done: remove the requirement that
roundtrip conversions of pointer-to-member are guaranteed (becomes
implementation defined, still works where it works today, doesn't where it
fails today). Another change would then be useful: provide a mechanism to
replace the intermediate point of the roundtrip.  For that you can either
extend the grammar to allow for a "pointer to member of unknown type" or
provide a different facility.  The simplest would be to have a way of
creating a buffer that is "large enough".

With such a buffer, expressions in the form 'T void::*dst =3D src;' become
'memcpy(&dst, &src, sizeof src)' (where 'src' is a pointer to member of
type 'T' in some class 'C').  The conversions in the opposite direction are
the inverse: 'memcpy(&ptr, buffer, sizeof ptr)'.

The two main differences between this design and the proposal is that more
information is lost in this simplified approach, and the syntax for use is
more cumbersome.  The former is something I am willing to accept, the
latter I believe is an advantage, as it forces the user into having a
variable of the correct type before the conversion is done.  In doing so,
the type becomes more obvious to the programmer.  Same example as I
provided before:

struct base { int member; };
struct derived : base { virtual void f(); };

// Proposal
int void::* p =3D &derived::member;
....
int derived::* q =3D p;

// Alternative
std::ptrmbr_buffer buffer;
int derived::* p =3D &derived::member;
std::memcpy(&buffer, &s, sizeof s);
....
int derived::* q;
std::memcpy(&q, &buffer, sizeof q);

Clearly the syntax is harder on the developer, but this is an uncommon
feature so a small amount of developers will be hit with the additional
burden.  On the other hand, while both pieces of code "look" sensible, the
first has undefined behavior and in this particular case undefined behavior
will produce the wrong result when the pointer to member is used to access
the variable. How many developers are able to spot the bug? How many
developers would be able to spot the bug when the definition of the types,
the assignment to the PMU and the extraction of the PMU live in three
separate translation units? Worse even, 'derived' might have started as a
non-polymorphic type where the code above is undefined behavior but "does"
(seems to do) the right thing, so it will escape testing, a later unrelated
change adds a virtual function (or a different base, or makes inheritance
virtual or...) and the sequence of conversions silently breaks.

The burden on the syntax is not that much, in most cases the PMU/buffer
would exist before the conversion/memcpy is done (a member in a
type-erasing object), so it amounts to different syntax for storing into
the PMU/buffer and forcing the separate copy from the buffer into the
destination PM.  The syntax can be improved by allowing 'reinterpret_cast'
directly from the buffer.  The negative impact of this additional syntactic
sugar is that without it, the buffer approach can be implemented as a pure
library extension (the library knows how large the buffer is, a
pointer-to-member is a POD so it can be memcpy-ed in and out of a large
enough buffer without problems.

The buffer approach "erases" more type information, and the simplified
version above would have a higher than needed size (pointers to member
functions are larger than pointers to data members), which could be
improved either by having two different buffer types for MFP vs. MDP, or
turning the buffer into a template that takes the type:

std::ptrmbr_buffer<int> a; // large enough for any int T::*
std::ptrmbr_buffer<int ()> b; // large enough for any int (T::*)()

TL;DR

The proposal aims to ease a niche with a core-language feature where a
library-only feature can get most of the way in a (possibly arguable) safer
way with little syntactic burden.

   David

On Mon, Feb 16, 2015 at 10:58 AM, Jean-Marc Bourguet <jm.bourguet@gmail.com=
>
wrote:

> Le lundi 16 f=C3=A9vrier 2015 15:58:57 UTC+1, Scott Prager a =C3=A9crit :
>>
>>
>>
>> On Monday, February 16, 2015 at 5:58:52 AM UTC-5, Markus Grech wrote:
>>>
>>> I have updated the proposal, feedback would be very appreciated.
>>> https://docs.google.com/document/d/1B4zWiym1twufigKA4RSXYR5xU4g32
>>> EJ8XNl_bzFtX08/edit?usp=3Dsharing
>>>
>>
>> One possible use-case that I don't see in this proposal:
>>
>> struct X { int mem; };
>> struct Y { int mem; };
>>
>>
>> int void::* p =3D X::mem;
>> auto xp =3D static_cast<int X::*>(p);  // (1)
>> auto yp =3D static_cast<int Y::*>(p);  // (2)
>>
>>
>> Obviously, *(1) *should be valid, and you describe such a round trip in
>> the proposal, but what about *(2)*?
>> Certainly not valid, but I don't see anything prohibiting it.
>>
>
> As usual, if there is nothing which give it a meaning, it is undefined.
> And UB -- explicit or just by lack of
> definition -- looks like the only reasonable thing in general.
>
> In the presented case X and Y are layout-compatible, there is an obvious
> meaning which we may want
> to mandate.
>
> --
> Jean-Marc
>
> --
>
> ---
> 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
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--001a11354faad22f0a050f48f42f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Sorry for looking like the bad guy here, but I am still un=
sure of the feature. Little added value and increased dangers as people don=
&#39;t quite understand pointers to members.<br><br>To be clear, the Itaniu=
m ABI does not have the pointer-to-member sizes described in the document t=
o adhere to the requirement of &#39;reinterpret_cast&#39;, but rather as th=
e result of the design of dynamic dispatch in that ABI (what value is &#39;=
this&#39; on entry to the final overrider?).<br><br>I am fine changing the =
standard to make VS implementation conformant. For that a single change nee=
ds to be done: remove the requirement that roundtrip conversions of pointer=
-to-member are guaranteed (becomes implementation defined, still works wher=
e it works today, doesn&#39;t where it fails today). Another change would t=
hen be useful: provide a mechanism to replace the intermediate point of the=
 roundtrip.=C2=A0 For that you can either extend the grammar to allow for a=
 &quot;pointer to member of unknown type&quot; or provide a different facil=
ity.=C2=A0 The simplest would be to have a way of creating a buffer that is=
 &quot;large enough&quot;.=C2=A0<br><br>With such a buffer, expressions in =
the form &#39;T void::*dst =3D src;&#39; become &#39;memcpy(&amp;dst, &amp;=
src, sizeof src)&#39; (where &#39;src&#39; is a pointer to member of type &=
#39;T&#39; in some class &#39;C&#39;).=C2=A0 The conversions in the opposit=
e direction are the inverse: &#39;memcpy(&amp;ptr, buffer, sizeof ptr)&#39;=
..<br><br>The two main differences between this design and the proposal is t=
hat more information is lost in this simplified approach, and the syntax fo=
r use is more cumbersome.=C2=A0 The former is something I am willing to acc=
ept, the latter I believe is an advantage, as it forces the user into havin=
g a variable of the correct type before the conversion is done.=C2=A0 In do=
ing so, the type becomes more obvious to the programmer.=C2=A0 Same example=
 as I provided before:<br><br>struct base { int member; };<br>struct derive=
d : base { virtual void f(); };<br><br>// Proposal<br>int void::* p =3D &am=
p;derived::member;<div>...<br>int derived::* q =3D p;<br><br>// Alternative=
<br>std::ptrmbr_buffer buffer;<div>int derived::* p =3D &amp;derived::membe=
r;<br>std::memcpy(&amp;buffer, &amp;s, sizeof s);</div><div>...</div><div>i=
nt derived::* q;<br>std::memcpy(&amp;q, &amp;buffer, sizeof q);<br><br>Clea=
rly the syntax is harder on the developer, but this is an uncommon feature =
so a small amount of developers will be hit with the additional burden.=C2=
=A0 On the other hand, while both pieces of code &quot;look&quot; sensible,=
 the first has undefined behavior and in this particular case undefined beh=
avior will produce the wrong result when the pointer to member is used to a=
ccess the variable. How many developers are able to spot the bug? How many =
developers would be able to spot the bug when the definition of the types, =
the assignment to the PMU and the extraction of the PMU live in three separ=
ate translation units? Worse even, &#39;derived&#39; might have started as =
a non-polymorphic type where the code above is undefined behavior but &quot=
;does&quot; (seems to do) the right thing, so it will escape testing, a lat=
er unrelated change adds a virtual function (or a different base, or makes =
inheritance virtual or...) and the sequence of conversions silently breaks.=
<br><br>The burden on the syntax is not that much, in most cases the PMU/bu=
ffer would exist before the conversion/memcpy is done (a member in a type-e=
rasing object), so it amounts to different syntax for storing into the PMU/=
buffer and forcing the separate copy from the buffer into the destination P=
M.=C2=A0 The syntax can be improved by allowing &#39;reinterpret_cast&#39; =
directly from the buffer.=C2=A0 The negative impact of this additional synt=
actic sugar is that without it, the buffer approach can be implemented as a=
 pure library extension (the library knows how large the buffer is, a point=
er-to-member is a POD so it can be memcpy-ed in and out of a large enough b=
uffer without problems.<br><br>The buffer approach &quot;erases&quot; more =
type information, and the simplified version above would have a higher than=
 needed size (pointers to member functions are larger than pointers to data=
 members), which could be improved either by having two different buffer ty=
pes for MFP vs. MDP, or turning the buffer into a template that takes the t=
ype:<br><br>std::ptrmbr_buffer&lt;int&gt; a; // large enough for any int T:=
:*<br>std::ptrmbr_buffer&lt;int ()&gt; b; // large enough for any int (T::*=
)()<br><br>TL;DR<br><br>The proposal aims to ease a niche with a core-langu=
age feature where a library-only feature can get most of the way in a (poss=
ibly arguable) safer way with little syntactic burden.<br><br>=C2=A0 =C2=A0=
David</div></div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_q=
uote">On Mon, Feb 16, 2015 at 10:58 AM, Jean-Marc Bourguet <span dir=3D"ltr=
">&lt;<a href=3D"mailto:jm.bourguet@gmail.com" target=3D"_blank">jm.bourgue=
t@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr">Le lundi 16 f=C3=A9vrier 2015 15:58:57 UTC+1, Scott Prager a =C3=
=A9crit=C2=A0:<span class=3D""><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><br><br>On Monday, February 16, 2015 at 5:58:52 AM UTC-5, Mark=
us Grech wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><fo=
nt color=3D"#000000" face=3D"Arial"><span style=3D"font-size:15px;white-spa=
ce:pre-wrap">I have updated the proposal, feedback would be very appreciate=
d.</span></font><div><a href=3D"https://docs.google.com/document/d/1B4zWiym=
1twufigKA4RSXYR5xU4g32EJ8XNl_bzFtX08/edit?usp=3Dsharing" rel=3D"nofollow" t=
arget=3D"_blank">https://docs.google.com/<u></u>document/d/<u></u>1B4zWiym1=
twufigKA4RSXYR5xU4g32<u></u>EJ8XNl_bzFtX08/edit?usp=3D<u></u>sharing</a></d=
iv></div></blockquote><div><br></div><div>One possible use-case that I don&=
#39;t see in this proposal:</div><div><br></div><div style=3D"border:1px so=
lid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)=
"><code><div><span style=3D"color:#008">struct</span><span style=3D"color:#=
000"> X </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">int</span><span style=3D"color:#000"> =
mem</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#008">struct</span><span style=3D"color:#000"> Y <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">int</span><span style=3D"color:#000"> mem</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">};</span><span style=3D"color:#000"><br><br><br></sp=
an><span style=3D"color:#008">int</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">void</span><span style=3D"color:#660">::*</span>=
<span style=3D"color:#000"> p </span><span style=3D"color:#660">=3D</span><=
span style=3D"color:#000"> X</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">mem</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> xp </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">static_cast</span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#008">int</span><=
span style=3D"color:#000"> X</span><span style=3D"color:#660">::*&gt;(</spa=
n><span style=3D"color:#000">p</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"> =C2=A0</span><span style=3D"color:#800">// (1)</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</=
span><span style=3D"color:#000"> yp </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> </span><span style=3D"color:#008">static_c=
ast</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">=
int</span><span style=3D"color:#000"> Y</span><span style=3D"color:#660">::=
*&gt;(</span><span style=3D"color:#000">p</span><span style=3D"color:#660">=
);</span><span style=3D"color:#000"> =C2=A0</span><span style=3D"color:#800=
">// (2)</span></div></code></div><div><br></div><div><br></div><div>Obviou=
sly, <i>(1) </i>should be valid, and you describe such a round trip in the =
proposal, but what about <i>(2)</i>?</div><div>Certainly not valid, but I d=
on&#39;t see anything prohibiting it.</div></div></blockquote><div><br></di=
v></span><div>As usual, if there is nothing which give it a meaning, it is =
undefined. And UB -- explicit or just by lack of</div><div>definition -- lo=
oks like the only reasonable thing in general.</div><div><br></div><div>In =
the presented case X and Y are layout-compatible, there is an obvious meani=
ng which we may want</div><div>to mandate.</div><span class=3D"HOEnZb"><fon=
t color=3D"#888888"><div><br></div><div>--=C2=A0</div><div>Jean-Marc</div><=
/font></span></div><div class=3D"HOEnZb"><div class=3D"h5">

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></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&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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11354faad22f0a050f48f42f--

.
