Topic: N4144, EWG 30: std::packer vs std::tuple


Author: David Krauss <potswa@gmail.com>
Date: Wed, 15 Oct 2014 09:33:48 +0800
Raw View
--Apple-Mail=_21362041-1711-4862-A1C8-7E96F5AFC0FE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

Hello Bill and Stephan,

I don't think std::packer really has a place in the standard library. It sa=
crifices convenience and efficiency, and it may encourage bad habits, compa=
red to std::tuple.


1. Runtime usage
---
packer can serve as a base class. However this is meaningless, as its essen=
tial features cannot be inherited. (A subclass of a specialization is not a=
 specialization. Most beginners do not initially grasp this.) It can serve =
as a dispatching tag, but in this role it's missing information about how t=
he packed types are related to the overload. In these cases, the user is be=
tter off defining a tag class:

template< typename >
base_descriptive_tag {};

template< typename >
param_descriptive_dispatch_tag {};

Even if there's no risk of collision between several independent uses of pa=
cker, it is significantly more expressive to mention a generic tag< packer<=
 ... > >, to express the tag design pattern to the reader, than to leave it=
 as simply packer. Having taken this step, it makes no difference to substi=
tute tuple for packer, since the specialization is never instantiated.


2. Convenience
---
If the ultimate result of metaprocessing is not a tag, it's probably a tupl=
e. Indeed, many tags coexist with and describe tuples. Turning a tuple into=
 a tag is easy, as illustrated above.

The opposite way, converting a packer into a tuple, requires a rebind opera=
tion, which may be unintuitive. Typecasts often trip up beginners in any la=
nguage, and TMP is no different. Unlike the conversion from tuple/packer to=
 user_tag, rebinding requires a library metafunction and doesn't serve much=
 descriptive purpose.

A metafunction whose input is a runtime tuple must likewise rebind it to pa=
cker before doing anything. This is also very common. Most real-world metap=
rocessing is "thin," with few intermediate results between the input and ou=
tput, and opportunistic reuse of intermediate results. This is also the ide=
al way for metaprocessing to be structured.

Thin functions still benefit from leveraging a rich standard library, but c=
onverting to and from special metaprocessing-only types would add bulk and =
could get users into the wrong mind-set.


3. Efficiency
---
Rebinding carries the cost of instantiating the rebind_to_tuple metafunctio=
n, and the cost of having named specializations of both packer and tuple. I=
n my experience, tuples are more often the end result of metaprocessing tha=
n tags are, and packers shouldn't be used directly as tags anyway. The choi=
ce of packer strictly increases the compiler's burden of named specializati=
ons.

The compile-time cost of rebinding may be quite significant if the compiler=
's internal representation of each specialization uniquely owns its paramet=
er list, requiring list copies.


4. Instantiation
---
packer can always be instantiated, but there is no reason this should ever =
happen, unless it's used at runtime. Metaprocessing should never incur inst=
antiation of metadata types, which represents unnecessary overhead. (Perhap=
s a small amount of overhead per empty class, but there are certainly ways =
that can add up.)

Pure metafunctions as in N4144 should be guaranteed not to instantiate thei=
r arguments, be they tuple or packer.


5. Genericness
---
The "tuple-like access" interfaces are already specialized for things besid=
es tuple. A new packer library would require packer_element and packer_size=
, which would exactly coincide with tuple_element and tuple_size. The overl=
ap would be redundant and confusing.


I had planned to submit a paper to Urbana on this topic, but it didn't make=
 the final cut. (I did submit seven, and this is my first meeting!) I might=
 still try to present these ideas, sooner or later.

 - Thanks for your consideration,
 David

--=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/.

--Apple-Mail=_21362041-1711-4862-A1C8-7E96F5AFC0FE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; -webk=
it-line-break: after-white-space;">Hello Bill and Stephan,<div><br></div><d=
iv>I don&rsquo;t think&nbsp;<font face=3D"Courier">std::packer</font>&nbsp;=
really has a place in the standard library. It sacrifices convenience and e=
fficiency, and it may encourage bad habits, compared to <font face=3D"Couri=
er">std::tuple</font>.</div><div><br></div><div><br></div><div>1. Runtime u=
sage</div><div>---</div><div><font face=3D"Courier">packer</font> can serve=
 as a base class. However this is meaningless, as its essential features ca=
nnot be inherited. (A subclass of a specialization is not a specialization.=
 Most beginners do not initially grasp this.) It can serve as a dispatching=
 tag, but in this role it&rsquo;s missing information about how the packed =
types are related to the overload. In these cases, the user is better off d=
efining a tag class:</div><div><br></div><div><font face=3D"Courier">templa=
te&lt; typename &gt;</font></div><div><font face=3D"Courier">base_descripti=
ve_tag {};</font></div><div><br></div><div><font face=3D"Courier">template&=
lt; typename &gt;</font></div><div><font face=3D"Courier">param_descriptive=
_dispatch_tag {};</font></div><div><br></div><div>Even if there&rsquo;s no =
risk of collision between several independent uses of <font face=3D"Courier=
">packer</font>, it is significantly more expressive to mention a generic <=
font face=3D"Courier">tag&lt; packer&lt; &hellip; &gt; &gt;</font>, to expr=
ess the tag design pattern to the reader, than to leave it as simply <font =
face=3D"Courier">packer</font>. Having taken this step, it makes no differe=
nce to substitute <font face=3D"Courier">tuple</font> for <font face=3D"Cou=
rier">packer</font>, since the specialization is never instantiated.</div><=
div><br></div><div><div><br></div><div>2. Convenience</div><div>---</div></=
div><div>If the ultimate result of metaprocessing is not a tag, it&rsquo;s =
probably a tuple. Indeed, many tags coexist with and describe tuples. Turni=
ng a tuple into a tag is easy, as illustrated above.</div><div><br></div><d=
iv>The opposite way, converting a <font face=3D"Courier">packer</font> into=
 a <font face=3D"Courier">tuple</font>, requires a rebind operation, which =
may be unintuitive. Typecasts often trip up beginners in any language, and =
TMP is no different. Unlike the conversion from <font face=3D"Courier">tupl=
e</font>/<font face=3D"Courier">packer</font> to <font face=3D"Courier">use=
r_tag</font>, rebinding requires a library metafunction and doesn&rsquo;t s=
erve much descriptive purpose.</div><div><br></div><div>A metafunction whos=
e input is a runtime <font face=3D"Courier">tuple</font>&nbsp;must likewise=
 rebind it to <font face=3D"Courier">packer</font> before doing anything. T=
his is also very common. Most real-world metaprocessing is &ldquo;thin,&rdq=
uo; with few intermediate results between the input and output, and opportu=
nistic reuse of intermediate results. This is also the ideal way for metapr=
ocessing to be structured.</div><div><br></div><div>Thin functions still be=
nefit from leveraging a rich standard library, but converting to and from s=
pecial metaprocessing-only types would add bulk and could get users into th=
e wrong mind-set.</div><div><br></div><div><br></div><div>3. Efficiency</di=
v><div>---</div><div>Rebinding carries the cost of instantiating the <font =
face=3D"Courier">rebind_to_tuple</font> metafunction, and the cost of havin=
g named specializations of both <font face=3D"Courier">packer</font> and <f=
ont face=3D"Courier">tuple</font>. In my experience, tuples are more often =
the end result of metaprocessing than tags are, and packers shouldn&rsquo;t=
 be used directly as tags anyway. The choice of <font face=3D"Courier">pack=
er</font> strictly increases the compiler&rsquo;s burden of named specializ=
ations.</div><div><br></div><div><div>The compile-time cost of rebinding ma=
y be quite significant if the compiler&rsquo;s internal representation of e=
ach specialization uniquely owns its parameter list, requiring list copies.=
</div><div><br></div></div><div><br></div><div>4. Instantiation</div><div>-=
--</div><div><font face=3D"Courier">packer</font> can always be instantiate=
d, but there is no reason this should ever happen, unless it&rsquo;s used a=
t runtime. Metaprocessing should never incur instantiation of metadata type=
s, which represents unnecessary overhead. (Perhaps a small amount of overhe=
ad per empty class, but there are certainly ways that can add up.)</div><di=
v><br></div><div>Pure metafunctions as in N4144 should be guaranteed not to=
 instantiate their arguments, be they&nbsp;<font face=3D"Courier">tuple</fo=
nt>&nbsp;or <font face=3D"Courier">packer</font>.</div><div><br></div><div>=
<br></div><div>5. Genericness</div><div>---</div><div>The &ldquo;tuple-like=
 access&rdquo; interfaces are already specialized for things besides tuple.=
 A new packer library would require <font face=3D"Courier">packer_element</=
font>&nbsp;and <font face=3D"Courier">packer_size</font>, which would exact=
ly coincide with <font face=3D"Courier">tuple_element</font> and <font face=
=3D"Courier">tuple_size</font>. The overlap would be redundant and confusin=
g.</div><div><br></div><div><br></div><div>I had planned to submit a paper =
to Urbana on this topic, but it didn&rsquo;t make the final cut. (I did sub=
mit seven, and this is my first meeting!) I might still try to present thes=
e ideas, sooner or later.</div><div><br></div><div><span class=3D"Apple-tab=
-span" style=3D"white-space:pre"> </span>- Thanks for your consideration,</=
div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>D=
avid</div><div><br></div></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&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 />

--Apple-Mail=_21362041-1711-4862-A1C8-7E96F5AFC0FE--

.


Author: "Stephan T. Lavavej" <stl@exchange.microsoft.com>
Date: Wed, 15 Oct 2014 20:31:34 +0000
Raw View
--_000_3b66cbb629654b629543bc6ed9a91503BN1PR03MB123namprd03pro_
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

This is Bill's work - I showed him some template trickery and he graciously=
 added my name to his paper (the latest version of which I have not yet rea=
d).

I will say one thing, though:

> packer can always be instantiated, but there is no reason this should eve=
r happen, unless it's used at runtime.
> Metaprocessing should never incur instantiation of metadata types, which =
represents unnecessary overhead.

As a professional template metaprogrammer, I use tag dispatch all day, ever=
y day.  It's more convenient than specializing structs (which I do, but rar=
ely), and avoids reaching for the massive hammer of SFINAE.

Tag dispatch is usually used for iterator strengths, but my implementations=
 of tuple_cat() and pair's piecewise construction use tag dispatch with int=
eger_sequences.

Being able to construct tags is important.

STL

From: David Krauss [mailto:potswa@gmail.com]
Sent: Tuesday, October 14, 2014 6:34 PM
To: stdbill.h@pobox.com; Stephan T. Lavavej
Cc: std-proposals@isocpp.org
Subject: N4144, EWG 30: std::packer vs std::tuple

Hello Bill and Stephan,

I don't think std::packer really has a place in the standard library. It sa=
crifices convenience and efficiency, and it may encourage bad habits, compa=
red to std::tuple.


1. Runtime usage
---
packer can serve as a base class. However this is meaningless, as its essen=
tial features cannot be inherited. (A subclass of a specialization is not a=
 specialization. Most beginners do not initially grasp this.) It can serve =
as a dispatching tag, but in this role it's missing information about how t=
he packed types are related to the overload. In these cases, the user is be=
tter off defining a tag class:

template< typename >
base_descriptive_tag {};

template< typename >
param_descriptive_dispatch_tag {};

Even if there's no risk of collision between several independent uses of pa=
cker, it is significantly more expressive to mention a generic tag< packer<=
 ... > >, to express the tag design pattern to the reader, than to leave it=
 as simply packer. Having taken this step, it makes no difference to substi=
tute tuple for packer, since the specialization is never instantiated.


2. Convenience
---
If the ultimate result of metaprocessing is not a tag, it's probably a tupl=
e. Indeed, many tags coexist with and describe tuples. Turning a tuple into=
 a tag is easy, as illustrated above.

The opposite way, converting a packer into a tuple, requires a rebind opera=
tion, which may be unintuitive. Typecasts often trip up beginners in any la=
nguage, and TMP is no different. Unlike the conversion from tuple/packer to=
 user_tag, rebinding requires a library metafunction and doesn't serve much=
 descriptive purpose.

A metafunction whose input is a runtime tuple must likewise rebind it to pa=
cker before doing anything. This is also very common. Most real-world metap=
rocessing is "thin," with few intermediate results between the input and ou=
tput, and opportunistic reuse of intermediate results. This is also the ide=
al way for metaprocessing to be structured.

Thin functions still benefit from leveraging a rich standard library, but c=
onverting to and from special metaprocessing-only types would add bulk and =
could get users into the wrong mind-set.


3. Efficiency
---
Rebinding carries the cost of instantiating the rebind_to_tuple metafunctio=
n, and the cost of having named specializations of both packer and tuple. I=
n my experience, tuples are more often the end result of metaprocessing tha=
n tags are, and packers shouldn't be used directly as tags anyway. The choi=
ce of packer strictly increases the compiler's burden of named specializati=
ons.

The compile-time cost of rebinding may be quite significant if the compiler=
's internal representation of each specialization uniquely owns its paramet=
er list, requiring list copies.


4. Instantiation
---
packer can always be instantiated, but there is no reason this should ever =
happen, unless it's used at runtime. Metaprocessing should never incur inst=
antiation of metadata types, which represents unnecessary overhead. (Perhap=
s a small amount of overhead per empty class, but there are certainly ways =
that can add up.)

Pure metafunctions as in N4144 should be guaranteed not to instantiate thei=
r arguments, be they tuple or packer.


5. Genericness
---
The "tuple-like access" interfaces are already specialized for things besid=
es tuple. A new packer library would require packer_element and packer_size=
, which would exactly coincide with tuple_element and tuple_size. The overl=
ap would be redundant and confusing.


I had planned to submit a paper to Urbana on this topic, but it didn't make=
 the final cut. (I did submit seven, and this is my first meeting!) I might=
 still try to present these ideas, sooner or later.

            - Thanks for your consideration,
            David

--=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/.

--_000_3b66cbb629654b629543bc6ed9a91503BN1PR03MB123namprd03pro_
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
>
<meta name=3D"Generator" content=3D"Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
 {font-family:Courier;
 panose-1:2 7 4 9 2 2 5 2 4 4;}
@font-face
 {font-family:Courier;
 panose-1:2 7 4 9 2 2 5 2 4 4;}
@font-face
 {font-family:Calibri;
 panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
 {font-family:Tahoma;
 panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
 {font-family:Verdana;
 panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
 {margin:0in;
 margin-bottom:.0001pt;
 font-size:12.0pt;
 font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
 {mso-style-priority:99;
 color:blue;
 text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
 {mso-style-priority:99;
 color:purple;
 text-decoration:underline;}
span.apple-tab-span
 {mso-style-name:apple-tab-span;}
span.EmailStyle18
 {mso-style-type:personal-reply;
 font-family:"Verdana","sans-serif";
 color:windowtext;}
..MsoChpDefault
 {mso-style-type:export-only;
 font-size:10.0pt;}
@page WordSection1
 {size:8.5in 11.0in;
 margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
 {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang=3D"EN-US" link=3D"blue" vlink=3D"purple">
<div class=3D"WordSection1">
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">This is Bill's work - I showed him some template tricker=
y and he graciously added my name to his paper (the latest version of which=
 I have not yet read).<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;"><o:p>&nbsp;</o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">I will say one thing, though:<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;"><o:p>&nbsp;</o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">&gt; packer can always be instantiated, but there is no =
reason this should ever happen, unless it&#8217;s used at runtime.<o:p></o:=
p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">&gt; Metaprocessing should never incur instantiation of =
metadata types, which represents unnecessary overhead.<o:p></o:p></span></p=
>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;"><o:p>&nbsp;</o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">As a professional template metaprogrammer, I use tag dis=
patch all day, every day.&nbsp; It's more convenient than specializing stru=
cts (which I do, but rarely), and avoids reaching for the massive
 hammer of SFINAE.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;"><o:p>&nbsp;</o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">Tag dispatch is usually used for iterator strengths, but=
 my implementations of tuple_cat() and pair's piecewise construction use ta=
g dispatch with integer_sequences.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;"><o:p>&nbsp;</o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">Being able to construct tags is important.<o:p></o:p></s=
pan></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;"><o:p>&nbsp;</o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;">STL<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-family:&quot;Verdana&quot;,&quot=
;sans-serif&quot;"><o:p>&nbsp;</o:p></span></p>
<div>
<div style=3D"border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in =
0in 0in">
<p class=3D"MsoNormal"><b><span style=3D"font-size:10.0pt;font-family:&quot=
;Tahoma&quot;,&quot;sans-serif&quot;">From:</span></b><span style=3D"font-s=
ize:10.0pt;font-family:&quot;Tahoma&quot;,&quot;sans-serif&quot;"> David Kr=
auss [mailto:potswa@gmail.com]
<br>
<b>Sent:</b> Tuesday, October 14, 2014 6:34 PM<br>
<b>To:</b> stdbill.h@pobox.com; Stephan T. Lavavej<br>
<b>Cc:</b> std-proposals@isocpp.org<br>
<b>Subject:</b> N4144, EWG 30: std::packer vs std::tuple<o:p></o:p></span><=
/p>
</div>
</div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
<p class=3D"MsoNormal">Hello Bill and Stephan,<o:p></o:p></p>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">I don&#8217;t think&nbsp;<span style=3D"font-family:=
Courier">std::packer</span>&nbsp;really has a place in the standard library=
.. It sacrifices convenience and efficiency, and it may encourage bad habits=
, compared to
<span style=3D"font-family:Courier">std::tuple</span>.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">1. Runtime usage<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">---<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-family:Courier">packer</span> ca=
n serve as a base class. However this is meaningless, as its essential feat=
ures cannot be inherited. (A subclass of a specialization is not a speciali=
zation. Most beginners do not initially
 grasp this.) It can serve as a dispatching tag, but in this role it&#8217;=
s missing information about how the packed types are related to the overloa=
d. In these cases, the user is better off defining a tag class:<o:p></o:p><=
/p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-family:Courier">template&lt; typ=
ename &gt;</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-family:Courier">base_descriptive=
_tag {};</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-family:Courier">template&lt; typ=
ename &gt;</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-family:Courier">param_descriptiv=
e_dispatch_tag {};</span><o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">Even if there&#8217;s no risk of collision between s=
everal independent uses of
<span style=3D"font-family:Courier">packer</span>, it is significantly more=
 expressive to mention a generic
<span style=3D"font-family:Courier">tag&lt; packer&lt; &#8230; &gt; &gt;</s=
pan>, to express the tag design pattern to the reader, than to leave it as =
simply
<span style=3D"font-family:Courier">packer</span>. Having taken this step, =
it makes no difference to substitute
<span style=3D"font-family:Courier">tuple</span> for <span style=3D"font-fa=
mily:Courier">
packer</span>, since the specialization is never instantiated.<o:p></o:p></=
p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">2. Convenience<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">---<o:p></o:p></p>
</div>
</div>
<div>
<p class=3D"MsoNormal">If the ultimate result of metaprocessing is not a ta=
g, it&#8217;s probably a tuple. Indeed, many tags coexist with and describe=
 tuples. Turning a tuple into a tag is easy, as illustrated above.<o:p></o:=
p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">The opposite way, converting a <span style=3D"font-f=
amily:Courier">
packer</span> into a <span style=3D"font-family:Courier">tuple</span>, requ=
ires a rebind operation, which may be unintuitive. Typecasts often trip up =
beginners in any language, and TMP is no different. Unlike the conversion f=
rom
<span style=3D"font-family:Courier">tuple</span>/<span style=3D"font-family=
:Courier">packer</span> to
<span style=3D"font-family:Courier">user_tag</span>, rebinding requires a l=
ibrary metafunction and doesn&#8217;t serve much descriptive purpose.<o:p><=
/o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">A metafunction whose input is a runtime <span style=
=3D"font-family:Courier">
tuple</span>&nbsp;must likewise rebind it to <span style=3D"font-family:Cou=
rier">packer</span> before doing anything. This is also very common. Most r=
eal-world metaprocessing is &#8220;thin,&#8221; with few intermediate resul=
ts between the input and output, and opportunistic
 reuse of intermediate results. This is also the ideal way for metaprocessi=
ng to be structured.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">Thin functions still benefit from leveraging a rich =
standard library, but converting to and from special metaprocessing-only ty=
pes would add bulk and could get users into the wrong mind-set.<o:p></o:p><=
/p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">3. Efficiency<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">---<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">Rebinding carries the cost of instantiating the <spa=
n style=3D"font-family:Courier">
rebind_to_tuple</span> metafunction, and the cost of having named specializ=
ations of both
<span style=3D"font-family:Courier">packer</span> and <span style=3D"font-f=
amily:Courier">
tuple</span>. In my experience, tuples are more often the end result of met=
aprocessing than tags are, and packers shouldn&#8217;t be used directly as =
tags anyway. The choice of
<span style=3D"font-family:Courier">packer</span> strictly increases the co=
mpiler&#8217;s burden of named specializations.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<div>
<p class=3D"MsoNormal">The compile-time cost of rebinding may be quite sign=
ificant if the compiler&#8217;s internal representation of each specializat=
ion uniquely owns its parameter list, requiring list copies.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">4. Instantiation<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">---<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span style=3D"font-family:Courier">packer</span> ca=
n always be instantiated, but there is no reason this should ever happen, u=
nless it&#8217;s used at runtime. Metaprocessing should never incur instant=
iation of metadata types, which represents
 unnecessary overhead. (Perhaps a small amount of overhead per empty class,=
 but there are certainly ways that can add up.)<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">Pure metafunctions as in N4144 should be guaranteed =
not to instantiate their arguments, be they&nbsp;<span style=3D"font-family=
:Courier">tuple</span>&nbsp;or
<span style=3D"font-family:Courier">packer</span>.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">5. Genericness<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">---<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">The &#8220;tuple-like access&#8221; interfaces are a=
lready specialized for things besides tuple. A new packer library would req=
uire
<span style=3D"font-family:Courier">packer_element</span>&nbsp;and <span st=
yle=3D"font-family:Courier">
packer_size</span>, which would exactly coincide with <span style=3D"font-f=
amily:Courier">
tuple_element</span> and <span style=3D"font-family:Courier">tuple_size</sp=
an>. The overlap would be redundant and confusing.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal">I had planned to submit a paper to Urbana on this to=
pic, but it didn&#8217;t make the final cut. (I did submit seven, and this =
is my first meeting!) I might still try to present these ideas, sooner or l=
ater.<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span class=3D"apple-tab-span">&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>- Thanks for your cons=
ideration,<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><span class=3D"apple-tab-span">&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>David<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
</div>
</div>
</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&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 />

--_000_3b66cbb629654b629543bc6ed9a91503BN1PR03MB123namprd03pro_--

.


Author: Bill Seymour <stdbill.h@pobox.com>
Date: Wed, 15 Oct 2014 16:09:41 -0500
Raw View
Thanks for the kind words, Stephan.

David, what got me started down this road is the desire
to have better iterator tags.  See N4124.  Whatever
mechanism we come up with for that, if any, must be
quietly upward-compatible with existing iterator tags
which, in turn, must be constructible with close to zero
run-time overhead.

Also, it occurs to me that the examples I show in N4124
might benefit from some mechanism for adding and
subtracting types from parameter packs.  Standard
library vendors who would have to implement the
new tags if we adopt them might be able to get rid
of some of the copy-and-paste anti-pattern that I,
not entirely without shame 8-), have in N4124.
(I haven't actually thought about that yet, however.)

--Bill Seymour


On Wed, Oct 15, 2014 at 3:31 PM, Stephan T. Lavavej
<stl@exchange.microsoft.com> wrote:
> This is Bill's work - I showed him some template trickery and he gracious=
ly
> added my name to his paper (the latest version of which I have not yet
> read).
>
>
>
> I will say one thing, though:
>
>
>
>> packer can always be instantiated, but there is no reason this should ev=
er
>> happen, unless it=E2=80=99s used at runtime.
>
>> Metaprocessing should never incur instantiation of metadata types, which
>> represents unnecessary overhead.
>
>
>
> As a professional template metaprogrammer, I use tag dispatch all day, ev=
ery
> day.  It's more convenient than specializing structs (which I do, but
> rarely), and avoids reaching for the massive hammer of SFINAE.
>
>
>
> Tag dispatch is usually used for iterator strengths, but my implementatio=
ns
> of tuple_cat() and pair's piecewise construction use tag dispatch with
> integer_sequences.
>
>
>
> Being able to construct tags is important.
>
>
>
> STL
>
>
>
> From: David Krauss [mailto:potswa@gmail.com]
> Sent: Tuesday, October 14, 2014 6:34 PM
> To: stdbill.h@pobox.com; Stephan T. Lavavej
> Cc: std-proposals@isocpp.org
> Subject: N4144, EWG 30: std::packer vs std::tuple
>
>
>
> Hello Bill and Stephan,
>
>
>
> I don=E2=80=99t think std::packer really has a place in the standard libr=
ary. It
> sacrifices convenience and efficiency, and it may encourage bad habits,
> compared to std::tuple.
>
>
>
>
>
> 1. Runtime usage
>
> ---
>
> packer can serve as a base class. However this is meaningless, as its
> essential features cannot be inherited. (A subclass of a specialization i=
s
> not a specialization. Most beginners do not initially grasp this.) It can
> serve as a dispatching tag, but in this role it=E2=80=99s missing informa=
tion about
> how the packed types are related to the overload. In these cases, the use=
r
> is better off defining a tag class:
>
>
>
> template< typename >
>
> base_descriptive_tag {};
>
>
>
> template< typename >
>
> param_descriptive_dispatch_tag {};
>
>
>
> Even if there=E2=80=99s no risk of collision between several independent =
uses of
> packer, it is significantly more expressive to mention a generic tag<
> packer< =E2=80=A6 > >, to express the tag design pattern to the reader, t=
han to
> leave it as simply packer. Having taken this step, it makes no difference=
 to
> substitute tuple for packer, since the specialization is never instantiat=
ed.
>
>
>
>
>
> 2. Convenience
>
> ---
>
> If the ultimate result of metaprocessing is not a tag, it=E2=80=99s proba=
bly a
> tuple. Indeed, many tags coexist with and describe tuples. Turning a tupl=
e
> into a tag is easy, as illustrated above.
>
>
>
> The opposite way, converting a packer into a tuple, requires a rebind
> operation, which may be unintuitive. Typecasts often trip up beginners in
> any language, and TMP is no different. Unlike the conversion from
> tuple/packer to user_tag, rebinding requires a library metafunction and
> doesn=E2=80=99t serve much descriptive purpose.
>
>
>
> A metafunction whose input is a runtime tuple must likewise rebind it to
> packer before doing anything. This is also very common. Most real-world
> metaprocessing is =E2=80=9Cthin,=E2=80=9D with few intermediate results b=
etween the input
> and output, and opportunistic reuse of intermediate results. This is also
> the ideal way for metaprocessing to be structured.
>
>
>
> Thin functions still benefit from leveraging a rich standard library, but
> converting to and from special metaprocessing-only types would add bulk a=
nd
> could get users into the wrong mind-set.
>
>
>
>
>
> 3. Efficiency
>
> ---
>
> Rebinding carries the cost of instantiating the rebind_to_tuple
> metafunction, and the cost of having named specializations of both packer
> and tuple. In my experience, tuples are more often the end result of
> metaprocessing than tags are, and packers shouldn=E2=80=99t be used direc=
tly as tags
> anyway. The choice of packer strictly increases the compiler=E2=80=99s bu=
rden of
> named specializations.
>
>
>
> The compile-time cost of rebinding may be quite significant if the
> compiler=E2=80=99s internal representation of each specialization uniquel=
y owns its
> parameter list, requiring list copies.
>
>
>
>
>
> 4. Instantiation
>
> ---
>
> packer can always be instantiated, but there is no reason this should eve=
r
> happen, unless it=E2=80=99s used at runtime. Metaprocessing should never =
incur
> instantiation of metadata types, which represents unnecessary overhead.
> (Perhaps a small amount of overhead per empty class, but there are certai=
nly
> ways that can add up.)
>
>
>
> Pure metafunctions as in N4144 should be guaranteed not to instantiate th=
eir
> arguments, be they tuple or packer.
>
>
>
>
>
> 5. Genericness
>
> ---
>
> The =E2=80=9Ctuple-like access=E2=80=9D interfaces are already specialize=
d for things
> besides tuple. A new packer library would require packer_element and
> packer_size, which would exactly coincide with tuple_element and tuple_si=
ze.
> The overlap would be redundant and confusing.
>
>
>
>
>
> I had planned to submit a paper to Urbana on this topic, but it didn=E2=
=80=99t make
> the final cut. (I did submit seven, and this is my first meeting!) I migh=
t
> still try to present these ideas, sooner or later.
>
>
>
>             - Thanks for your consideration,
>
>             David
>
>

--=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/.

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 16 Oct 2014 14:49:16 +0800
Raw View
--Apple-Mail=_70289539-04F3-4163-8E84-74A36D220E7E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On 2014-10-16, at 4:31 AM, Stephan T. Lavavej <stl@exchange.microsoft.com> =
wrote:

> As a professional template metaprogrammer, I use tag dispatch all day, ev=
ery day.  It's more convenient than specializing structs (which I do, but r=
arely), and avoids reaching for the massive hammer of SFINAE.


Certainly. This is the first point I addressed: programmers should be encou=
raged to use descriptive tags, rather than always use a type with some othe=
r generic purpose which mechanically works because it happens to be empty.

Even a generic template< typename > class tag {}; helps by explicitly sayin=
g that tag dispatch is being used. Passing or inheriting from packer itself=
 offers a cryptic semantic disconnect, and may interfere with overloading o=
n or inheriting from another packer tag.


On 2014-10-16, at 5:09 AM, Bill Seymour <stdbill.h@pobox.com> wrote:

> Thanks for the kind words, Stephan.
>=20
> David, what got me started down this road is the desire
> to have better iterator tags.  See N4124.  Whatever
> mechanism we come up with for that, if any, must be
> quietly upward-compatible with existing iterator tags
> which, in turn, must be constructible with close to zero
> run-time overhead.

This isn't possible with the general packer model, and now I see you've def=
ined explicit specializations for certain combinations of tags:

>   But to avoid breaking legacy code that depends on iterator tag inherita=
nce, we could apply the inheritance to packer specializations:
>     template<>
>     struct packer<reference_tag,
>                   lvalue_tag,
>                   rvalue_tag,
>                   equality_comparable_tag,
>                   multipass_tag>
>              : input_iterator_tag { };
This terribly brittle. Fundamentally new functionality deserves a new templ=
ate name, and you can only observe this specialization by listing exactly t=
hose facets in the correct order. There's no room for adding new facets lat=
er.

What you seem to be reaching for is a *set* of tags, not a *list* of tags. =
Searching for the first occurrence of an item in a parameter pack requires =
O(N) specializations. Set membership testing is more efficiently done as a =
cast (which is how current iterator tags work) or an overloaded function ca=
ll.

Why not do,

struct input_iterator_tag
    : composite_iterator_tag< type_set<
        reference_tag,
        lvalue_tag,
        rvalue_tag,
        equality_comparable_tag,
        multipass_tag > >
    {};

where type_set has bases or members to allow membership testing with little=
 compile-time complexity.

--=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/.

--Apple-Mail=_70289539-04F3-4163-8E84-74A36D220E7E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014&=
ndash;10&ndash;16, at 4:31 AM, Stephan T. Lavavej &lt;<a href=3D"mailto:stl=
@exchange.microsoft.com">stl@exchange.microsoft.com</a>&gt; wrote:</div><br=
 class=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div style=
=3D"margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: 'Times New Roma=
n', serif; font-style: normal; font-variant: normal; font-weight: normal; l=
etter-spacing: normal; line-height: normal; orphans: auto; text-align: star=
t; text-indent: 0px; text-transform: none; white-space: normal; widows: aut=
o; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style=3D"font-=
family: Verdana, sans-serif;">As a professional template metaprogrammer, I =
use tag dispatch all day, every day.&nbsp; It's more convenient than specia=
lizing structs (which I do, but rarely), and avoids reaching for the massiv=
e hammer of SFINAE.</span></div></blockquote></div><div><br></div><div>Cert=
ainly. This is the first point I addressed: programmers should be encourage=
d to use descriptive tags, rather than always use a type with some other ge=
neric purpose which mechanically works because it happens to be empty.</div=
><div><br></div><div>Even a generic&nbsp;<font face=3D"Courier">template&lt=
; typename &gt; class tag {};</font> helps by explicitly saying that tag di=
spatch is being used. Passing or inheriting from <font face=3D"Courier">pac=
ker</font>&nbsp;itself offers a cryptic semantic disconnect, and may interf=
ere with overloading on or inheriting from another <font face=3D"Courier">p=
acker</font> tag.</div><div><br></div><div><br></div><div><div>On 2014&ndas=
h;10&ndash;16, at 5:09 AM, Bill Seymour &lt;<a href=3D"mailto:stdbill.h@pob=
ox.com">stdbill.h@pobox.com</a>&gt; wrote:</div><br class=3D"Apple-intercha=
nge-newline"><blockquote type=3D"cite">Thanks for the kind words, Stephan.<=
br><br>David, what got me started down this road is the desire<br>to have b=
etter iterator tags. &nbsp;See N4124. &nbsp;Whatever<br>mechanism we come u=
p with for that, if any, must be<br>quietly upward-compatible with existing=
 iterator tags<br>which, in turn, must be constructible with close to zero<=
br>run-time overhead.<br></blockquote><br></div><div>This isn&rsquo;t possi=
ble with the general packer model, and now I see you&rsquo;ve defined expli=
cit specializations for certain combinations of tags:</div><div><br></div><=
div><blockquote type=3D"cite">&nbsp; But to avoid breaking legacy code that=
 depends on iterator tag inheritance,
we could apply the inheritance to <tt>packer</tt> specializations:

<pre>    template&lt;&gt;
    struct packer&lt;reference_tag,
                  lvalue_tag,
                  rvalue_tag,
                  equality_comparable_tag,
                  multipass_tag&gt;
             : input_iterator_tag { };
</pre></blockquote><div>This terribly brittle. Fundamentally new functional=
ity deserves a new template name, and you can only observe this specializat=
ion by listing exactly those facets in the correct order. There&rsquo;s no =
room for adding new facets later.</div></div><div><br></div><div>What you s=
eem to be reaching for is a *<i>set</i>* of tags, not a *<i>list</i>* of ta=
gs. Searching for the first occurrence of an item in a parameter pack requi=
res O(N) specializations. Set membership testing is more efficiently done a=
s a cast (which is how current iterator tags work) or an overloaded functio=
n call.</div><div><br></div><div>Why not do,</div><div><br></div><div><font=
 face=3D"Courier">struct input_iterator_tag</font></div><div><font face=3D"=
Courier">&nbsp; &nbsp; : composite_iterator_tag&lt; type_set&lt;</font></di=
v><div><span style=3D"font-family: Courier;">&nbsp; &nbsp;</span><span styl=
e=3D"font-family: Courier;">&nbsp;</span><span style=3D"font-family: Courie=
r;">&nbsp; &nbsp;</span><span style=3D"font-family: Courier;">&nbsp;</span>=
<span style=3D"font-family: Courier;">reference_tag,</span></div><div><span=
 style=3D"font-family: Courier;">&nbsp; &nbsp;</span><span style=3D"font-fa=
mily: Courier;">&nbsp;</span><span style=3D"font-family: Courier;">&nbsp; &=
nbsp;</span><span style=3D"font-family: Courier;">&nbsp;</span><span style=
=3D"font-family: Courier;">lvalue_tag,</span></div><div><span style=3D"font=
-family: Courier;">&nbsp; &nbsp;</span><span style=3D"font-family: Courier;=
">&nbsp;</span><span style=3D"font-family: Courier;">&nbsp; &nbsp;</span><s=
pan style=3D"font-family: Courier;">&nbsp;</span><span style=3D"font-family=
: Courier;">rvalue_tag,</span></div><div><span style=3D"font-family: Courie=
r;">&nbsp; &nbsp;</span><span style=3D"font-family: Courier;">&nbsp;</span>=
<span style=3D"font-family: Courier;">&nbsp; &nbsp;</span><span style=3D"fo=
nt-family: Courier;">&nbsp;</span><span style=3D"font-family: Courier;">equ=
ality_comparable_tag,</span></div><div><span style=3D"font-family: Courier;=
">&nbsp; &nbsp;</span><span style=3D"font-family: Courier;">&nbsp;</span><s=
pan style=3D"font-family: Courier;">&nbsp; &nbsp;</span><span style=3D"font=
-family: Courier;">&nbsp;</span><span style=3D"font-family: Courier;">multi=
pass_tag &gt; &gt;</span></div><div><font face=3D"Courier">&nbsp; &nbsp; {}=
;</font></div><div><br></div><div>where <font face=3D"Courier">type_set</fo=
nt>&nbsp;has bases or members to allow membership testing with little compi=
le-time complexity.</div><div><br></div></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&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 />

--Apple-Mail=_70289539-04F3-4163-8E84-74A36D220E7E--

.