Topic: Components" template with implicitly defined partial


Author: "wkaras via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sat, 27 Feb 2016 13:09:26 -0800 (PST)
Raw View
------=_Part_549_1325354316.1456607366342
Content-Type: multipart/alternative;
 boundary="----=_Part_550_1328416426.1456607366342"

------=_Part_550_1328416426.1456607366342
Content-Type: text/plain; charset=UTF-8

Maybe something more general would make sense?  A "primitive" template
named "Components" with this interface:
<pre>
template <
  class Target,
  template <typename Member_type, Member_type Target::*mptr>
    class Op,
  typename Param>
struct Components
  {
    bool operator () (Param & param);
  };
</pre>
The Op parameter is presumed to fulfill the constraint:
<pre>
Param & param;
Op<Member_type, &Target::member> op;
bool b = op(param);
</pre>
for all data members and base classes of the class Target.  The function
operator of Components would be generated implicitly.  It would instantiate
Op for each component of Target, create an instance of the instantiated
class, and call its function operator as shown in the constraint above,
forwarding to it the parameter 'param'.  If the call returned false, the
function operator of Components would return false immediately.  If all the
calls for components returned true, the Components operator would also
return true.

For example, for this class:
<pre>
struct A { int i, j; double x; };
</pre>
the compiler would implicitly generate the equivalent of the following
partial specialization of Components:
<pre>
template <
  template <typename Member_type, Member_type A::*mptr> class Op,
  typename Param>
struct Components<A, Op, Param>
  {
    bool operator () (Param & param)
      {
        return(
          Op<int, &A::i>()(param) &&
          Op<int, &A::j>()(param) &&
          Op<double, &A::x>()(param));
      }
  };
</pre>
This would make it possible to define a default operator == as a library
template:
<pre>
template <class Target>
class Equality_op;

template <class Target>
class Equality_param
  {
    friend class Equality_op<Target>;

    const Target &op1, &op2;

  public:
    Equality_param(const Target &op1_, const Target &op2_)
      : op1(op1_), op2(op2_) { }
  };

template <class Target>
struct Equality_op
  {
    template <typename Member_type, Member_type Target::*mptr>
    struct Op
      {
        bool operator () (Equality_param<Target> & param)
          {
            return(param.op1.*mptr == param.op2.*mptr);
          }
      };
  };

template <class Target>
bool operator == (const Target &op1, const Target &op2)
  {
    Equality_param<Target> param(op1, op2);

    Components<
      Target, Equality_op<Target>::template Op, Equality_param<Target> > c;

    return(c(param));
  }
</pre>
Likewise for default operators > and <.

This implies that member pointers can point to base classes, which I'm
guessing is an idea that's been rejected before.  So doing this would
create "pressure" to accept the syntax:
<pre>
Base Derived::*p = &Derived::Base;
</pre>
There would also be a need for another "primitive" template
Components_no_virt_base that would skip over virtual base classes I think.

A nice thing about this approach is that the default == operator could
sometimes be "fixed" rather than discarded.  For example, suppose the
default == operator worked for a class "Big" except for one data member
"argh", which was a pointer to a heap object.  One could handle this with
an overriding instantiation of "Equality_op":
<pre>
template <>
struct Equality_op<Big>
  {
    template <>
    struct Op<Argh, &Big::argh>
      {
        bool operator () (Equality_param<Target> & param)
          {
            // ...
          }
      };
  };
</pre>

--
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/cacd9802-0288-4350-923c-ecdc070dfaad%40isocpp.org.

------=_Part_550_1328416426.1456607366342
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Maybe something more general would make sense?=C2=A0 A &qu=
ot;primitive&quot; template named &quot;Components&quot; with this interfac=
e:<br>&lt;pre&gt;<br>template &lt;<br>=C2=A0 class Target,<br>=C2=A0 templa=
te &lt;typename Member_type, Member_type Target::*mptr&gt;<br>=C2=A0=C2=A0=
=C2=A0 class Op,<br>=C2=A0 typename Param&gt;<br>struct Components<br>=C2=
=A0 {<br>=C2=A0=C2=A0=C2=A0 bool operator () (Param &amp; param);<br>=C2=A0=
 };<br>&lt;/pre&gt;<br>The Op parameter is presumed to fulfill the constrai=
nt:<br>&lt;pre&gt;<br>Param &amp; param;<br>Op&lt;Member_type, &amp;Target:=
:member&gt; op; <br>bool b =3D op(param);<br>&lt;/pre&gt;<br>for all data m=
embers and base classes of the class Target.=C2=A0 The function operator of=
 Components would be generated implicitly.=C2=A0 It would instantiate Op fo=
r each component of Target, create an instance of the instantiated class, a=
nd call its function operator as shown in the constraint above, forwarding =
to it the parameter &#39;param&#39;.=C2=A0 If the call returned false, the =
function operator of Components would return false immediately.=C2=A0 If al=
l the calls for components returned true, the Components operator would als=
o return true.<br><br>For example, for this class:<br>&lt;pre&gt;<br>struct=
 A { int i, j; double x; };<br>&lt;/pre&gt;<br>the compiler would implicitl=
y generate the equivalent of the following partial specialization of Compon=
ents:<br>&lt;pre&gt;<br>template &lt;<br>=C2=A0 template &lt;typename Membe=
r_type, Member_type A::*mptr&gt; class Op,<br>=C2=A0 typename Param&gt;<br>=
struct Components&lt;A, Op, Param&gt;<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 boo=
l operator () (Param &amp; param)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return(<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Op&lt;int, &amp;A::i&gt;()(param) &amp;&a=
mp;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Op&lt;int, &a=
mp;A::j&gt;()(param) &amp;&amp;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 Op&lt;double, &amp;A::x&gt;()(param));<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 }<br>=C2=A0 };<br>&lt;/pre&gt;<br>This would make it possib=
le to define a default operator =3D=3D as a library template:<br>&lt;pre&gt=
;<br>template &lt;class Target&gt;<br>class Equality_op;<br><br>template &l=
t;class Target&gt;<br>class Equality_param<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=
=A0 friend class Equality_op&lt;Target&gt;;<br><br>=C2=A0=C2=A0=C2=A0 const=
 Target &amp;op1, &amp;op2;<br><br>=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0 Equ=
ality_param(const Target &amp;op1_, const Target &amp;op2_)<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 : op1(op1_), op2(op2_) { }<br>=C2=A0 };<br><br>template =
&lt;class Target&gt;<br>struct Equality_op<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=
=A0 template &lt;typename Member_type, Member_type Target::*mptr&gt;<br>=C2=
=A0=C2=A0=C2=A0 struct Op<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bool operator () (Equality_param&lt;Targe=
t&gt; &amp; param)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 return(param.op1.*mptr =3D=3D param.op2.*mptr);<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br=
>=C2=A0 };<br><br>template &lt;class Target&gt;<br>bool operator =3D=3D (co=
nst Target &amp;op1, const Target &amp;op2)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=
=A0 Equality_param&lt;Target&gt; param(op1, op2);<br><br>=C2=A0=C2=A0=C2=A0=
 Components&lt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Target, Equality_op&lt;Ta=
rget&gt;::template Op, Equality_param&lt;Target&gt; &gt; c;<br><br>=C2=A0=
=C2=A0=C2=A0 return(c(param));<br>=C2=A0 }<br>&lt;/pre&gt;<br>Likewise for =
default operators &gt; and &lt;.<br><br>This implies that member pointers c=
an point to base classes, which I&#39;m guessing is an idea that&#39;s been=
 rejected before.=C2=A0 So doing this would create &quot;pressure&quot; to =
accept the syntax:<br>&lt;pre&gt;<br>Base Derived::*p =3D &amp;Derived::Bas=
e;<br>&lt;/pre&gt;<br>There would also be a need for another &quot;primitiv=
e&quot; template Components_no_virt_base that would skip over virtual base =
classes I think.<br><br>A nice thing about this approach is that the defaul=
t =3D=3D operator could sometimes be &quot;fixed&quot; rather than discarde=
d.=C2=A0 For example, suppose the default =3D=3D operator worked for a clas=
s &quot;Big&quot; except for one data member &quot;argh&quot;, which was a =
pointer to a heap object.=C2=A0 One could handle this with an overriding in=
stantiation of &quot;Equality_op&quot;:<br>&lt;pre&gt;<br>template &lt;&gt;=
<br>struct Equality_op&lt;Big&gt;<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 templat=
e &lt;&gt;<br>=C2=A0=C2=A0=C2=A0 struct Op&lt;Argh, &amp;Big::argh&gt;<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 bool operator () (Equality_param&lt;Target&gt; &amp; param)<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ...<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };=
<br>=C2=A0 };<br>&lt;/pre&gt;<br></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/cacd9802-0288-4350-923c-ecdc070dfaad%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cacd9802-0288-4350-923c-ecdc070dfaad=
%40isocpp.org</a>.<br />

------=_Part_550_1328416426.1456607366342--
------=_Part_549_1325354316.1456607366342--

.


Author: "'Walt Karas' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sat, 27 Feb 2016 13:18:34 -0800 (PST)
Raw View
------=_Part_291_1848091743.1456607914116
Content-Type: multipart/alternative;
 boundary="----=_Part_292_435338990.1456607914121"

------=_Part_292_435338990.1456607914121
Content-Type: text/plain; charset=UTF-8

A "primitive" template named "Components" with this interface:

template <
  class Target,
  template <typename Member_type, Member_type Target::*mptr>
    class Op,
  typename Param>
struct Components
  {
    bool operator () (Param & param);
  };

The Op parameter is presumed to fulfill the constraint:

Param & param;
Op<Member_type, &Target::member> op;
bool b = op(param);

for all data members and base classes of the class Target.  The function
operator of Components would be generated implicitly.  It would instantiate
Op for each component of Target, create an instance of the instantiated
class, and call its function operator as shown in the constraint above,
forwarding to it the parameter 'param'.  If the call returned false, the
function operator of Components would return false immediately.  If all the
calls for components returned true, the Components operator would also
return true.

For example, for this class:

struct A { int i, j; double x; };

the compiler would implicitly generate the equivalent of the following
partial specialization of Components:

template <
  template <typename Member_type, Member_type A::*mptr> class Op,
  typename Param>
struct Components<A, Op, Param>
  {
    bool operator () (Param & param)
      {
        return(
          Op<int, &A::i>()(param) &&
          Op<int, &A::j>()(param) &&
          Op<double, &A::x>()(param));
      }
  };

This would make it possible to define a default operator == as a library
template:

template <class Target>
class Equality_op;

template <class Target>
class Equality_param
  {
    friend class Equality_op<Target>;

    const Target &op1, &op2;

  public:
    Equality_param(const Target &op1_, const Target &op2_)
      : op1(op1_), op2(op2_) { }
  };

template <class Target>
struct Equality_op
  {
    template <typename Member_type, Member_type Target::*mptr>
    struct Op
      {
        bool operator () (Equality_param<Target> & param)
          {
            return(param.op1.*mptr == param.op2.*mptr);
          }
      };
  };

template <class Target>
bool operator == (const Target &op1, const Target &op2)
  {
    Equality_param<Target> param(op1, op2);

    Components<
      Target, Equality_op<Target>::template Op, Equality_param<Target> > c;

    return(c(param));
  }

Likewise for default operators > and <.

This implies that member pointers can point to base classes, which I'm
guessing is an idea that's been rejected before.  So doing this would
create "pressure" to accept the syntax:

Base Derived::*p = &Derived::Base;

There would also be a need for another "primitive" template
Components_no_virt_base that would skip over virtual base classes I think.

A nice thing about this approach is that the default == operator could
sometimes be "fixed" rather than discarded.  For example, suppose the
default == operator worked for a class "Big" except for one data member
"argh", which was a pointer to a heap object.  One could handle this with
an overriding instantiation of "Equality_op":

template <>
struct Equality_op<Big>
  {
    template <>
    struct Op<Argh, &Big::argh>
      {
        bool operator () (Equality_param<Target> & param)
          {
            // ...
          }
      };
  };

--
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/fd64d8c9-703d-45d8-a9b2-4b8a222c02f0%40isocpp.org.

------=_Part_292_435338990.1456607914121
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">A &quot;primitive&quot; template named &quot;Components&qu=
ot; with this interface:<br><br>template &lt;<br>=C2=A0 class Target,<br>=
=C2=A0 template &lt;typename Member_type, Member_type Target::*mptr&gt;<br>=
=C2=A0=C2=A0=C2=A0 class Op,<br>=C2=A0 typename Param&gt;<br>struct Compone=
nts<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 bool operator () (Param &amp; param);=
<br>=C2=A0 };<br><br>The Op parameter is presumed to fulfill the constraint=
:<br><br>Param &amp; param;<br>Op&lt;Member_type, &amp;Target::member&gt; o=
p; <br>bool b =3D op(param);<br><br>for all data members and base classes o=
f the class Target.=C2=A0 The function operator of Components would be gene=
rated implicitly.=C2=A0 It would instantiate Op for each component of Targe=
t, create an instance of the instantiated class, and call its function oper=
ator as shown in the constraint above, forwarding to it the parameter &#39;=
param&#39;.=C2=A0 If the call returned false, the function operator of Comp=
onents would return false immediately.=C2=A0 If all the calls for component=
s returned true, the Components operator would also return true.<br><br>For=
 example, for this class:<br><br>struct A { int i, j; double x; };<br><br>t=
he compiler would implicitly generate the equivalent of the following parti=
al specialization of Components:<br><br>template &lt;<br>=C2=A0 template &l=
t;typename Member_type, Member_type A::*mptr&gt; class Op,<br>=C2=A0 typena=
me Param&gt;<br>struct Components&lt;A, Op, Param&gt;<br>=C2=A0 {<br>=C2=A0=
=C2=A0=C2=A0 bool operator () (Param &amp; param)<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return(<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Op&lt;int, &amp;A::i&gt;()=
(param) &amp;&amp;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 Op&lt;int, &amp;A::j&gt;()(param) &amp;&amp;<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Op&lt;double, &amp;A::x&gt;()(param));<br=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0 };<br><br>This would make it po=
ssible to define a default operator =3D=3D as a library template:<br><br>te=
mplate &lt;class Target&gt;<br>class Equality_op;<br><br>template &lt;class=
 Target&gt;<br>class Equality_param<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 frien=
d class Equality_op&lt;Target&gt;;<br><br>=C2=A0=C2=A0=C2=A0 const Target &=
amp;op1, &amp;op2;<br><br>=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0 Equality_par=
am(const Target &amp;op1_, const Target &amp;op2_)<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 : op1(op1_), op2(op2_) { }<br>=C2=A0 };<br><br>template &lt;class=
 Target&gt;<br>struct Equality_op<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 templat=
e &lt;typename Member_type, Member_type Target::*mptr&gt;<br>=C2=A0=C2=A0=
=C2=A0 struct Op<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 bool operator () (Equality_param&lt;Target&gt; &am=
p; param)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return(p=
aram.op1.*mptr =3D=3D param.op2.*mptr);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br>=C2=A0 }=
;<br><br>template &lt;class Target&gt;<br>bool operator =3D=3D (const Targe=
t &amp;op1, const Target &amp;op2)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 Equali=
ty_param&lt;Target&gt; param(op1, op2);<br><br>=C2=A0=C2=A0=C2=A0 Component=
s&lt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Target, Equality_op&lt;Target&gt;::=
template Op, Equality_param&lt;Target&gt; &gt; c;<br><br>=C2=A0=C2=A0=C2=A0=
 return(c(param));<br>=C2=A0 }<br><br>Likewise for default operators &gt; a=
nd &lt;.<br><br>This implies that member pointers can point to base classes=
, which I&#39;m guessing is an idea that&#39;s been rejected before.=C2=A0 =
So doing this would create &quot;pressure&quot; to accept the syntax:<br><b=
r>Base Derived::*p =3D &amp;Derived::Base;<br><br>There would also be a nee=
d for another &quot;primitive&quot; template Components_no_virt_base that w=
ould skip over virtual base classes I think.<br><br>A nice thing about this=
 approach is that the default =3D=3D operator could sometimes be &quot;fixe=
d&quot; rather than discarded.=C2=A0 For example, suppose the default =3D=
=3D operator worked for a class &quot;Big&quot; except for one data member =
&quot;argh&quot;, which was a pointer to a heap object.=C2=A0 One could han=
dle this with an overriding instantiation of &quot;Equality_op&quot;:<br><b=
r>template &lt;&gt;<br>struct Equality_op&lt;Big&gt;<br>=C2=A0 {<br>=C2=A0=
=C2=A0=C2=A0 template &lt;&gt;<br>=C2=A0=C2=A0=C2=A0 struct Op&lt;Argh, &am=
p;Big::argh&gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 bool operator () (Equality_param&lt;Target&gt; &am=
p; param)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ...<b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 };<br>=C2=A0 };<br></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/fd64d8c9-703d-45d8-a9b2-4b8a222c02f0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fd64d8c9-703d-45d8-a9b2-4b8a222c02f0=
%40isocpp.org</a>.<br />

------=_Part_292_435338990.1456607914121--
------=_Part_291_1848091743.1456607914116--

.