Topic: Safe 'type erasure' without runtime memory allocation
Author: phdscholar80@outlook.com
Date: Sun, 13 Jan 2019 00:36:52 -0800 (PST)
Raw View
------=_Part_1327_453490285.1547368612158
Content-Type: multipart/alternative;
boundary="----=_Part_1328_1736742267.1547368612160"
------=_Part_1328_1736742267.1547368612160
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Hi,
Many times we create a variable from a specific instantiation of a class=20
template, but then need to assign a value from a different instantiation.=
=20
This is the classic case of mixing custom allocators for standard=20
containers with the default allocator. C++17 solves this through=20
polymorphic memory resources. But it would be nice to have an easy solution=
=20
available for programmers. Generally, the 'type erasure' pattern involves=
=20
the use of:
1. boost/std any - which is inefficient because of the need to query the=20
object or it forces use of the visitor pattern which scatters the logic all=
=20
over the place.
2. A custom abstract interface - which leads to runtime memory allocation.
It would be nice if there was a mechanism by which the compiler could defer=
=20
the determination of size till link time, and then choose a size that fits=
=20
the largest size needed. In effect, it allows the programmer to control the=
=20
tradeoff between higher static memory usage vs performance cost of memory=
=20
allocation. Here, I would like to explore such an option, using type=20
erasure of lambdas as a specific example.
template <typename =E2=80=A6>
erasure function;
template <typename R, typename ...Args>
erasure function<R(Args=E2=80=A6)>
{
using _Me =3D function<R(Args=E2=80=A6)>;
// erasure implies these are pure virtual
R operator()(Args=E2=80=A6);
template <typename Callable>
_Me& operator=3D(Callable&&); =20
};
template <typename Callable, typename R, typename ...Args>
class callable_container : public function<R(Args=E2=80=A6)>
{
// The implementation of erased templates is hidden from users. Users=
=20
can only see the public erasure interface.
R operator()(Args=E2=80=A6 args) override { /* Implement */ }
// The set of concrete types that are passed to operator=3D anywhere in=
=20
the program,
// which are determined through template argument deduction,
// determines the amount of memory to be allocated for _c.
_Me& operator=3D(Callable&& c) override { /* Implement */ }
Callable _c;
};
---------------------------------
In module A:
class A
{
public:
template <typename Handler>
void SetHandler(Handler&& h) { mHandler =3D std::forward<Handler>(h); }
void Op()
{
// Do work
auto ret =3D mHandler(1, 2);
}
private:
Callable<int(int, int)> mHandler;
};
// As a first iteration, objects containing erased types can only be=20
constructed in global scope.
A globalA;
---------------------------------
In module B:
class B
{
public:
void f()
{
globalA.SetHandler([&i, f =3D f, &d](auto&&=E2=80=A6) {});
globalA.Op();
}
private:
float f;
int i;
double d;
};
---------------------------------
In module C:
class C
{
public:
void f()
{
globalA.SetHandler([this](auto&&=E2=80=A6) {});
globalA.Op();
}
private:
float f;
int i;
double d;
};
The compiler defers the size determination of A to link time when all the=
=20
information is available.
I would like the experts' opinion on this. Is this something that could be=
=20
possible?
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/57a4a1ff-5607-4ac9-8903-0c3bcd9f4bbc%40isocpp.or=
g.
------=_Part_1328_1736742267.1547368612160
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hi,</div><div><br></div><div>Many times we create a v=
ariable from a specific instantiation of a class template, but then need to=
assign a value from a different instantiation. This is the classic case of=
mixing custom allocators for standard containers with the default allocato=
r. C++17 solves this through polymorphic memory resources. But it would be =
nice to have an easy solution available for programmers. Generally, the =
9;type erasure' pattern involves the use of:</div><div><br></div><div>1=
.. boost/std any - which is inefficient because of the need to query the obj=
ect or it forces use of the visitor pattern which scatters the logic all ov=
er the place.</div><div>2. A custom abstract interface - which leads to run=
time memory allocation.</div><div><br></div><div>It would be nice if there =
was a mechanism by which the compiler could defer the determination of size=
till link time, and then choose a size that fits the largest size needed. =
In effect, it allows the programmer to control the tradeoff between higher =
static memory usage vs performance cost of memory allocation. Here, I would=
like to explore such an option, using type erasure of lambdas as a specifi=
c example.</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;">template</span><s=
pan 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: #008;">typename</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">=E2=80=A6></span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br>erasure </span><span class=3D"styled-b=
y-prettify" style=3D"color: #008;">function</span><span class=3D"styled-by-=
prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prettify"=
style=3D"color: #000;"><br><br><br></span><span class=3D"styled-by-prettif=
y" style=3D"color: #008;">template</span><span class=3D"styled-by-prettify"=
style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D=
"color: #660;"><</span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">typename</span><span class=3D"styled-by-prettify" style=3D"color: =
#000;"> R</span><span class=3D"styled-by-prettify" style=3D"color: #660;">,=
</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><s=
pan class=3D"styled-by-prettify" style=3D"color: #008;">typename</span><spa=
n class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">...</span><span class=3D"sty=
led-by-prettify" style=3D"color: #606;">Args</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">></span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;"><br>erasure </span><span class=3D"styled-by-pre=
ttify" style=3D"color: #008;">function</span><span class=3D"styled-by-prett=
ify" style=3D"color: #660;"><</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #000;">R</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #660;">(</span><span class=3D"styled-by-prettify" style=3D"color: #60=
6;">Args</span><span class=3D"styled-by-prettify" style=3D"color: #660;">=
=E2=80=A6)></span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #660;">{<=
/span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =
=C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #008;">usi=
ng</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> _Me </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: #008;">function</span><span class=
=3D"styled-by-prettify" style=3D"color: #660;"><</span><span class=3D"st=
yled-by-prettify" style=3D"color: #000;">R</span><span class=3D"styled-by-p=
rettify" style=3D"color: #660;">(</span><span class=3D"styled-by-prettify" =
style=3D"color: #606;">Args</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">=E2=80=A6)>;</span><span class=3D"styled-by-prettify" =
style=3D"color: #000;"><br><br><br>=C2=A0 =C2=A0 </span><span class=3D"styl=
ed-by-prettify" style=3D"color: #800;">// erasure implies these are pure vi=
rtual</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br><=
br><br>=C2=A0 =C2=A0 R </span><span class=3D"styled-by-prettify" style=3D"c=
olor: #008;">operator</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">()(</span><span class=3D"styled-by-prettify" style=3D"color: #60=
6;">Args</span><span class=3D"styled-by-prettify" style=3D"color: #660;">=
=E2=80=A6);</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
><br><br><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=
=3D"color: #008;">template</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #660;"><</span><span class=3D"styled-by-prettify" style=3D"color: #008=
;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
> </span><span class=3D"styled-by-prettify" style=3D"color: #606;">Callable=
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">></span=
><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=
=A0 _Me</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&am=
p;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span>=
<span class=3D"styled-by-prettify" style=3D"color: #008;">operator</span><s=
pan class=3D"styled-by-prettify" style=3D"color: #660;">=3D(</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #606;">Callable</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #660;">&&);</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"> =C2=A0 =C2=A0<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><br><br></span><span =
class=3D"styled-by-prettify" style=3D"color: #008;">template</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"st=
yled-by-prettify" style=3D"color: #660;"><</span><span class=3D"styled-b=
y-prettify" style=3D"color: #008;">typename</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify"=
style=3D"color: #606;">Callable</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #000;=
"> R</span><span class=3D"styled-by-prettify" style=3D"color: #660;">,</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span c=
lass=3D"styled-by-prettify" style=3D"color: #008;">typename</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"sty=
led-by-prettify" style=3D"color: #660;">...</span><span class=3D"styled-by-=
prettify" style=3D"color: #606;">Args</span><span class=3D"styled-by-pretti=
fy" style=3D"color: #660;">></span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D=
"color: #008;">class</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"> callable_container </span><span class=3D"styled-by-prettify" sty=
le=3D"color: #660;">:</span><span class=3D"styled-by-prettify" style=3D"col=
or: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #008;=
">public</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> <=
/span><span class=3D"styled-by-prettify" style=3D"color: #008;">function</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #660;"><</span><s=
pan class=3D"styled-by-prettify" style=3D"color: #000;">R</span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=3D"style=
d-by-prettify" style=3D"color: #606;">Args</span><span class=3D"styled-by-p=
rettify" style=3D"color: #660;">=E2=80=A6)></span><span class=3D"styled-=
by-prettify" style=3D"color: #000;"><br></span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-pret=
tify" style=3D"color: #800;">// The implementation of erased templates is h=
idden from users. Users can only see the public erasure interface.</span><s=
pan class=3D"styled-by-prettify" style=3D"color: #000;"><br><br><br>=C2=A0 =
=C2=A0 R </span><span class=3D"styled-by-prettify" style=3D"color: #008;">o=
perator</span><span class=3D"styled-by-prettify" style=3D"color: #660;">()(=
</span><span class=3D"styled-by-prettify" style=3D"color: #606;">Args</span=
><span class=3D"styled-by-prettify" style=3D"color: #660;">=E2=80=A6</span>=
<span class=3D"styled-by-prettify" style=3D"color: #000;"> args</span><span=
class=3D"styled-by-prettify" style=3D"color: #660;">)</span><span class=3D=
"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-b=
y-prettify" style=3D"color: #008;">override</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify"=
style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D=
"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #=
800;">/* Implement */</span><span class=3D"styled-by-prettify" style=3D"col=
or: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">}</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br><br=
>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #8=
00;">// The set of concrete types that are passed to operator=3D anywhere i=
n the program,</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"co=
lor: #800;">// which are determined through template argument deduction,</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =
=C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #800;">// =
determines the amount of memory to be allocated for _c.</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 _Me</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">&</span><span=
class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D=
"styled-by-prettify" style=3D"color: #008;">operator</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">=3D(</span><span class=3D"styled-=
by-prettify" style=3D"color: #606;">Callable</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">&&</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"> c</span><span class=3D"styled-by-prettif=
y" style=3D"color: #660;">)</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">override</span><span class=3D"styled-by-prettify" style=3D"color: =
#000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #660;">{<=
/span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><sp=
an class=3D"styled-by-prettify" style=3D"color: #800;">/* Implement */</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span c=
lass=3D"styled-by-prettify" style=3D"color: #660;">}</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"><br><br><br>=C2=A0 =C2=A0 </span>=
<span class=3D"styled-by-prettify" style=3D"color: #606;">Callable</span><s=
pan class=3D"styled-by-prettify" style=3D"color: #000;"> _c</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #660;">;</span><span class=3D"sty=
led-by-prettify" style=3D"color: #000;"><br></span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">};</span></div></code></div><div><br></di=
v><div><br></div><div>---------------------------------</div><div><br></div=
><div>In module A:</div><div><br></div><div class=3D"prettyprint" style=3D"=
border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-col=
or: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprett=
yprint"><span class=3D"styled-by-prettify" style=3D"color: #008;">class</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;"> A<br></span><=
span class=3D"styled-by-prettify" style=3D"color: #660;">{</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #008;">public</span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">:</span><span class=3D"styled-by-pret=
tify" style=3D"color: #000;"><br><br><br>=C2=A0 =C2=A0 </span><span class=
=3D"styled-by-prettify" style=3D"color: #008;">template</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #660;"><</span><span class=3D"styled-by-p=
rettify" style=3D"color: #008;">typename</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" st=
yle=3D"color: #606;">Handler</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">></span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" sty=
le=3D"color: #008;">void</span><span class=3D"styled-by-prettify" style=3D"=
color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #6=
06;">SetHandler</span><span class=3D"styled-by-prettify" style=3D"color: #6=
60;">(</span><span class=3D"styled-by-prettify" style=3D"color: #606;">Hand=
ler</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&&a=
mp;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> h</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #660;">)</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"> mHandler </span><span class=3D"styled-by-=
prettify" style=3D"color: #660;">=3D</span><span class=3D"styled-by-prettif=
y" style=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #660;">::</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;">forward</span><span class=3D"styled-by-prettify" style=3D"color=
: #660;"><</span><span class=3D"styled-by-prettify" style=3D"color: #606=
;">Handler</span><span class=3D"styled-by-prettify" style=3D"color: #660;">=
>(</span><span class=3D"styled-by-prettify" style=3D"color: #000;">h</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">);</span><span=
class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">}</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"><br><br><br>=C2=A0 =C2=A0 </span><span c=
lass=3D"styled-by-prettify" style=3D"color: #008;">void</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #606;">Op</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">()</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span class=3D"=
styled-by-prettify" style=3D"color: #800;">// Do work</span><span class=3D"=
styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
</span><span class=3D"styled-by-prettify" style=3D"color: #008;">auto</span=
><span class=3D"styled-by-prettify" style=3D"color: #000;"> ret </span><spa=
n class=3D"styled-by-prettify" style=3D"color: #660;">=3D</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> mHandler</span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=3D"style=
d-by-prettify" style=3D"color: #066;">1</span><span class=3D"styled-by-pret=
tify" style=3D"color: #660;">,</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"col=
or: #066;">2</span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">);</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=
=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #66=
0;">}</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br><=
br><br></span><span class=3D"styled-by-prettify" style=3D"color: #008;">pri=
vate</span><span class=3D"styled-by-prettify" style=3D"color: #660;">:</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><spa=
n class=3D"styled-by-prettify" style=3D"color: #606;">Callable</span><span =
class=3D"styled-by-prettify" style=3D"color: #660;"><</span><span class=
=3D"styled-by-prettify" style=3D"color: #008;">int</span><span class=3D"sty=
led-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #008;">int</span><span class=3D"styled-by-prettify"=
style=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D=
"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #=
008;">int</span><span class=3D"styled-by-prettify" style=3D"color: #660;">)=
></span><span class=3D"styled-by-prettify" style=3D"color: #000;"> mHand=
ler</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 class=
=3D"styled-by-prettify" style=3D"color: #000;"><br><br><br></span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #800;">// As a first iteration, o=
bjects containing erased types can only be constructed in global scope.</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;"><br><br><br>A =
globalA</span><span class=3D"styled-by-prettify" style=3D"color: #660;">;</=
span></div></code></div><div><br></div><div><br></div><div><div style=3D"ba=
ckground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-b=
ottom-style: none; border-bottom-width: 0px; border-image-outset: 0; border=
-image-repeat: stretch; border-image-slice: 100%; border-image-source: none=
; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-st=
yle: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bor=
der-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 3=
4, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 3=
4); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif; font-size: 13px; font-style: normal; font-variant: normal; font-w=
eight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; m=
argin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding=
-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-de=
coration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke=
-width: 0px; white-space: normal; word-spacing: 0px;">---------------------=
------------</div><div style=3D"background-color: transparent; border-botto=
m-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0=
px; border-image-outset: 0; border-image-repeat: stretch; border-image-slic=
e: 100%; border-image-source: none; border-image-width: 1; border-left-colo=
r: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border=
-right-color: rgb(34, 34, 34); border-right-style: none; border-right-width=
: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-to=
p-width: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot=
;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: no=
rmal; font-variant: normal; font-weight: 400; letter-spacing: normal; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphan=
s: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-t=
op: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tr=
ansform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-sp=
acing: 0px;"><br style=3D"background-attachment: scroll; background-clip: b=
order-box; background-color: transparent; background-image: none; backgroun=
d-origin: padding-box; background-position-x: 0%; background-position-y: 0%=
; background-repeat: repeat; background-size: auto; border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot=
;Helvetica&quot;,sans-serif; font-size: 13px; height: auto; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width: 0=
px; overflow: visible; overflow-x: visible; overflow-y: visible; padding-bo=
ttom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div>=
<div style=3D"background-color: transparent; border-bottom-color: rgb(34, 3=
4, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-o=
utset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-im=
age-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34)=
; border-left-style: none; border-left-width: 0px; border-right-color: rgb(=
34, 34, 34); border-right-style: none; border-right-width: 0px; border-top-=
color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; colo=
r: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">In mo=
dule B:</div><div style=3D"background-color: transparent; border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&am=
p;quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal;=
font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bot=
tom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2;=
padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0=
px; text-align: left; text-decoration: none; text-indent: 0px; text-transfo=
rm: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing=
: 0px;"><br style=3D"background-attachment: scroll; background-clip: border=
-box; background-color: transparent; background-image: none; background-ori=
gin: padding-box; background-position-x: 0%; background-position-y: 0%; bac=
kground-repeat: repeat; background-size: auto; border-bottom-color: rgb(34,=
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; co=
lor: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helv=
etica&quot;,sans-serif; font-size: 13px; height: auto; margin-bottom: 0=
px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width: 0px; o=
verflow: visible; overflow-x: visible; overflow-y: visible; padding-bottom:=
0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div =
style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34=
); border-bottom-style: none; border-bottom-width: 0px; border-image-outset=
: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-s=
ource: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bor=
der-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 3=
4, 34); border-right-style: none; border-right-width: 0px; border-top-color=
: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rg=
b(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&a=
mp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-l=
eft: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: le=
ft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-=
text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"></div></di=
v><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-pre=
ttify" style=3D"color: #008;">class</span><span class=3D"styled-by-prettify=
" style=3D"color: #000;"> B<br></span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #=
008;">public</span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">:</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br><br=
>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #0=
08;">void</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> =
f</span><span class=3D"styled-by-prettify" style=3D"color: #660;">()</span>=
<span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0=
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">{</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 globalA</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">.</span><span class=3D"styled-by-prettify" style=3D"color: #606;=
">SetHandler</span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">([&</span><span class=3D"styled-by-prettify" style=3D"color: #000;">i=
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">,</span><s=
pan class=3D"styled-by-prettify" style=3D"color: #000;"> f </span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #660;">=3D</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> f</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">,</span><span class=3D"styled-by-prettify=
" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">&</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;">d</span><span class=3D"styled-by-prettify" style=3D"color: #66=
0;">](</span><span class=3D"styled-by-prettify" style=3D"color: #008;">auto=
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&&=
=E2=80=A6)</span><span class=3D"styled-by-prettify" style=3D"color: #000;">=
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">{});</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 globalA</span><span class=3D"styled-by-prettify" style=3D=
"color: #660;">.</span><span class=3D"styled-by-prettify" style=3D"color: #=
606;">Op</span><span class=3D"styled-by-prettify" style=3D"color: #660;">()=
;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=
=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #660;"=
>}</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br><br>=
<br></span><span class=3D"styled-by-prettify" style=3D"color: #008;">privat=
e</span><span class=3D"styled-by-prettify" style=3D"color: #660;">:</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;"><br><br><br>=C2=A0=
=C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #008;">fl=
oat</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> f</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #660;">;</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span=
><span class=3D"styled-by-prettify" style=3D"color: #008;">int</span><span =
class=3D"styled-by-prettify" style=3D"color: #000;"> i</span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">;</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"=
styled-by-prettify" style=3D"color: #008;">double</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #000;"> d</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">};</span></div></code></div><div><br></div><div><br></div=
><div><div style=3D"background-color: transparent; border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; tex=
t-align: left; text-decoration: none; text-indent: 0px; text-transform: non=
e; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"=
><div style=3D"background-color: transparent; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-l=
eft: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: le=
ft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-=
text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">----------=
-----------------------</div><div style=3D"background-color: transparent; b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); font-size: 13px; font-styl=
e: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; =
margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; o=
rphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padd=
ing-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; te=
xt-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; wo=
rd-spacing: 0px;"><br style=3D"background-attachment: scroll; background-cl=
ip: border-box; background-color: transparent; background-image: none; back=
ground-origin: padding-box; background-position-x: 0%; background-position-=
y: 0%; background-repeat: repeat; background-size: auto; border-bottom-colo=
r: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bo=
rder-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100=
%; border-image-source: none; border-image-width: 1; border-left-color: rgb=
(34, 34, 34); border-left-style: none; border-left-width: 0px; border-right=
-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px;=
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-widt=
h: 0px; color: rgb(34, 34, 34); font-size: 13px; height: auto; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width: 0p=
x; overflow: visible; overflow-x: visible; overflow-y: visible; padding-bot=
tom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><=
div style=3D"background-color: transparent; border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color=
: rgb(34, 34, 34); font-size: 13px; font-style: normal; font-variant: norma=
l; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px=
; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;">In module C:=
</div><div style=3D"background-color: transparent; border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; color: rgb(34, 34, 34); font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br s=
tyle=3D"background-attachment: scroll; background-clip: border-box; backgro=
und-color: transparent; background-image: none; background-origin: padding-=
box; background-position-x: 0%; background-position-y: 0%; background-repea=
t: repeat; background-size: auto; border-bottom-color: rgb(34, 34, 34); bor=
der-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; b=
order-image-repeat: stretch; border-image-slice: 100%; border-image-source:=
none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-le=
ft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34)=
; border-right-style: none; border-right-width: 0px; border-top-color: rgb(=
34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, =
34, 34); font-size: 13px; height: auto; margin-bottom: 0px; margin-left: 0p=
x; margin-right: 0px; margin-top: 0px; min-width: 0px; overflow: visible; o=
verflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-left:=
0px; padding-right: 0px; padding-top: 0px;"></div><div style=3D"background=
-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-st=
yle: none; border-bottom-width: 0px; border-image-outset: 0; border-image-r=
epeat: stretch; border-image-slice: 100%; border-image-source: none; border=
-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: non=
e; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-righ=
t-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); =
border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font=
-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; le=
tter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0=
px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; pa=
dding-right: 0px; padding-top: 0px; text-align: left; text-decoration: none=
; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; w=
hite-space: normal; word-spacing: 0px;"></div></div><div class=3D"prettypri=
nt" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; b=
ackground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">class</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> =
C<br></span><span class=3D"styled-by-prettify" style=3D"color: #660;">{</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><sp=
an class=3D"styled-by-prettify" style=3D"color: #008;">public</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #660;">:</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"><br><br>=C2=A0 =C2=A0 </span><spa=
n class=3D"styled-by-prettify" style=3D"color: #008;">void</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"> f</span><span class=3D"sty=
led-by-prettify" style=3D"color: #660;">()</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"sty=
led-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 globalA</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #660;">.</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #606;">SetHandler</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #660;">([</span><span class=3D"=
styled-by-prettify" style=3D"color: #008;">this</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">](</span><span class=3D"styled-by-pret=
tify" style=3D"color: #008;">auto</span><span class=3D"styled-by-prettify" =
style=3D"color: #660;">&&=E2=80=A6)</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify"=
style=3D"color: #660;">{});</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 globalA</span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">.</span><span class=3D"style=
d-by-prettify" style=3D"color: #606;">Op</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">();</span><span class=3D"styled-by-prettify" =
style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-pr=
ettify" style=3D"color: #660;">}</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #000;"><br><br><br></span><span class=3D"styled-by-prettify"=
style=3D"color: #008;">private</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">:</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"><br><br><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prett=
ify" style=3D"color: #008;">float</span><span class=3D"styled-by-prettify" =
style=3D"color: #000;"> f</span><span class=3D"styled-by-prettify" style=3D=
"color: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"=
color: #008;">int</span><span class=3D"styled-by-prettify" style=3D"color: =
#000;"> i</span><span class=3D"styled-by-prettify" style=3D"color: #660;">;=
</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0=
=C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #008;">do=
uble</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> d</sp=
an><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 style=3D"background-color: transparent; border-bottom-color: rgb(34, 3=
4, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-o=
utset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-im=
age-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34)=
; border-left-style: none; border-left-width: 0px; border-right-color: rgb(=
34, 34, 34); border-right-style: none; border-right-width: 0px; border-top-=
color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; colo=
r: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br>T=
he compiler defers the size determination of A to link time when all the in=
formation is available.</div><div style=3D"background-color: transparent; b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; fon=
t-style: normal; font-variant: normal; font-weight: 400; letter-spacing: no=
rmal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: =
0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px=
; padding-top: 0px; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;"><br></div><div style=3D"background-color: transpare=
nt; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &quo=
t;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px=
; font-style: normal; font-variant: normal; font-weight: 400; letter-spacin=
g: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-=
top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right=
: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-inde=
nt: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space:=
normal; word-spacing: 0px;">I would like the experts' opinion on this.=
Is this something that could be possible?</div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/57a4a1ff-5607-4ac9-8903-0c3bcd9f4bbc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/57a4a1ff-5607-4ac9-8903-0c3bcd9f4bbc=
%40isocpp.org</a>.<br />
------=_Part_1328_1736742267.1547368612160--
------=_Part_1327_453490285.1547368612158--
.
Author: Barry Revzin <barry.revzin@gmail.com>
Date: Sun, 13 Jan 2019 07:25:27 -0800 (PST)
Raw View
------=_Part_1154_1240931882.1547393127304
Content-Type: multipart/alternative;
boundary="----=_Part_1155_1699276481.1547393127304"
------=_Part_1155_1699276481.1547393127304
Content-Type: text/plain; charset="UTF-8"
On Sunday, January 13, 2019 at 2:36:52 AM UTC-6, phdsch...@outlook.com
wrote:
>
> Hi,
>
> Many times we create a variable from a specific instantiation of a class
> template, but then need to assign a value from a different instantiation.
> This is the classic case of mixing custom allocators for standard
> containers with the default allocator. C++17 solves this through
> polymorphic memory resources. But it would be nice to have an easy solution
> available for programmers. Generally, the 'type erasure' pattern involves
> the use of:
>
> 1. boost/std any - which is inefficient because of the need to query the
> object or it forces use of the visitor pattern which scatters the logic all
> over the place.
> 2. A custom abstract interface - which leads to runtime memory allocation.
>
> It would be nice if there was a mechanism by which the compiler could
> defer the determination of size till link time, and then choose a size that
> fits the largest size needed. In effect, it allows the programmer to
> control the tradeoff between higher static memory usage vs performance cost
> of memory allocation. Here, I would like to explore such an option, using
> type erasure of lambdas as a specific example.
>
It's not clear to me what exactly you're looking for. I didn't understand
your example.
Have you seen, for instance, Dyno (https://github.com/ldionne/dyno/)? It
allows you to provide a fixed, local storage that avoids allocation, or a
custom-sized small buffer optimization. It's up to you to choose that
storage though - to pick some fixed number, etc. Maybe that's good enough?
--
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/34e00382-38d2-4645-b608-2894ccc3de56%40isocpp.org.
------=_Part_1155_1699276481.1547393127304
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, January 13, 2019 at 2:36:52 AM UTC-6, phdsch...=
@outlook.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div>Hi,</div><div><br></div><div>Many times we create a variable fro=
m a specific instantiation of a class template, but then need to assign a v=
alue from a different instantiation. This is the classic case of mixing cus=
tom allocators for standard containers with the default allocator. C++17 so=
lves this through polymorphic memory resources. But it would be nice to hav=
e an easy solution available for programmers. Generally, the 'type eras=
ure' pattern involves the use of:</div><div><br></div><div>1. boost/std=
any - which is inefficient because of the need to query the object or it f=
orces use of the visitor pattern which scatters the logic all over the plac=
e.</div><div>2. A custom abstract interface - which leads to runtime memory=
allocation.</div><div><br></div><div>It would be nice if there was a mecha=
nism by which the compiler could defer the determination of size till link =
time, and then choose a size that fits the largest size needed. In effect, =
it allows the programmer to control the tradeoff between higher static memo=
ry usage vs performance cost of memory allocation. Here, I would like to ex=
plore such an option, using type erasure of lambdas as a specific example.<=
/div></div></blockquote><div><br></div><div>It's not clear to me what e=
xactly you're looking for.=C2=A0 I didn't understand your example.<=
/div><div><br></div><div>Have you seen, for instance, Dyno (https://github.=
com/ldionne/dyno/)? It allows you to provide a fixed, local storage that av=
oids allocation, or a custom-sized small buffer optimization. It's up t=
o you to choose that storage though - to pick some fixed number, etc. Maybe=
that's good enough?</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/34e00382-38d2-4645-b608-2894ccc3de56%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/34e00382-38d2-4645-b608-2894ccc3de56=
%40isocpp.org</a>.<br />
------=_Part_1155_1699276481.1547393127304--
------=_Part_1154_1240931882.1547393127304--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 13 Jan 2019 10:39:17 -0800 (PST)
Raw View
------=_Part_1441_470529564.1547404757437
Content-Type: multipart/alternative;
boundary="----=_Part_1442_1228171613.1547404757438"
------=_Part_1442_1228171613.1547404757438
Content-Type: text/plain; charset="UTF-8"
As it currently stands, `sizeof` is a constant expression. And therefore, I
ought to be able to instantiate a template with
`sizeof(callable_container<Func>);`. What you want to do makes that
impossible. So you now need a new category of types whose sizes are not
constant expressions.
And such a property is viral. The size of
`optional<callable_container<Func>>` is *also* not a constant expression.
Nor is the size of anything that stores such a type. And so on.
Also, this poses a usability concern. What exactly happens if I instantiate
`callable_container` with a gigantic type? That doesn't just affect the
local instance of that object; it affects every instance *everywhere*. A
seemingly localized change can have far-reaching impacts. And there's
nothing I can actually do about it.
The nice thing about small storage optimization is that there is a strict
upper-limit on how big it can get, thus ensuring that things can't get
worse than a certain amount. What you're doing kind of breaks that, which
can cause quite a lot of damage.
--
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/606ad7e2-70c2-4c32-832b-324b018de5df%40isocpp.org.
------=_Part_1442_1228171613.1547404757438
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>As it currently stands, `sizeof` is a constant expres=
sion. And therefore, I ought to be able to instantiate a template with `siz=
eof(callable_container<Func>);`. What you want to do makes that impos=
sible. So you now need a new category of types whose sizes are not constant=
expressions.</div><div><br></div><div>And such a property is viral. The si=
ze of `optional<callable_container<Func>>` is <i>also</i> not a=
constant expression. Nor is the size of anything that stores such a type. =
And so on.<br></div><div><br></div><div>Also, this poses a usability concer=
n. What exactly happens if I instantiate `callable_container` with a gigant=
ic type? That doesn't just affect the local instance of that object; it=
affects every instance <i>everywhere</i>. A seemingly localized change can=
have far-reaching impacts. And there's nothing I can actually do about=
it.</div><div><br></div><div>The nice thing about small storage optimizati=
on is that there is a strict upper-limit on how big it can get, thus ensuri=
ng that things can't get worse than a certain amount. What you're d=
oing kind of breaks that, which can cause quite a lot of damage.<br></div><=
/div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/606ad7e2-70c2-4c32-832b-324b018de5df%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/606ad7e2-70c2-4c32-832b-324b018de5df=
%40isocpp.org</a>.<br />
------=_Part_1442_1228171613.1547404757438--
------=_Part_1441_470529564.1547404757437--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 13 Jan 2019 12:14:32 -0800 (PST)
Raw View
------=_Part_1195_1388654204.1547410472466
Content-Type: multipart/alternative;
boundary="----=_Part_1196_1399500879.1547410472467"
------=_Part_1196_1399500879.1547410472467
Content-Type: text/plain; charset="UTF-8"
On Sunday, January 13, 2019 at 1:39:17 PM UTC-5, Nicol Bolas wrote:
>
> As it currently stands, `sizeof` is a constant expression. And therefore,
> I ought to be able to instantiate a template with
> `sizeof(callable_container<Func>);`. What you want to do makes that
> impossible. So you now need a new category of types whose sizes are not
> constant expressions.
>
> And such a property is viral. The size of
> `optional<callable_container<Func>>` is *also* not a constant expression.
> Nor is the size of anything that stores such a type. And so on.
>
> Also, this poses a usability concern. What exactly happens if I
> instantiate `callable_container` with a gigantic type? That doesn't just
> affect the local instance of that object; it affects every instance
> *everywhere*. A seemingly localized change can have far-reaching impacts.
> And there's nothing I can actually do about it.
>
> The nice thing about small storage optimization is that there is a strict
> upper-limit on how big it can get, thus ensuring that things can't get
> worse than a certain amount. What you're doing kind of breaks that, which
> can cause quite a lot of damage.
>
Oh, and how exactly would this work across DLL/SO boundaries? Would
`callable_container<Func>`, for the same `Func` type, have different sizes
on different sides of the DLL/SO? After all, object sizes are static
properties; they cannot change based on which libraries are loaded. So how
does that work?
--
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/b271154f-88f6-481b-80ea-0a228492a129%40isocpp.org.
------=_Part_1196_1399500879.1547410472467
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, January 13, 2019 at 1:39:17 PM UTC-5, N=
icol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div>As it currently stands, `sizeof` is a constant expression. And the=
refore, I ought to be able to instantiate a template with `sizeof(callable_=
container<<wbr>Func>);`. What you want to do makes that impossible. S=
o you now need a new category of types whose sizes are not constant express=
ions.</div><div><br></div><div>And such a property is viral. The size of `o=
ptional<callable_container<<wbr>Func>>` is <i>also</i> not a co=
nstant expression. Nor is the size of anything that stores such a type. And=
so on.<br></div><div><br></div><div>Also, this poses a usability concern. =
What exactly happens if I instantiate `callable_container` with a gigantic =
type? That doesn't just affect the local instance of that object; it af=
fects every instance <i>everywhere</i>. A seemingly localized change can ha=
ve far-reaching impacts. And there's nothing I can actually do about it=
..</div><div><br></div><div>The nice thing about small storage optimization =
is that there is a strict upper-limit on how big it can get, thus ensuring =
that things can't get worse than a certain amount. What you're doin=
g kind of breaks that, which can cause quite a lot of damage.<br></div></di=
v></blockquote><div><br></div><div>Oh, and how exactly would this work acro=
ss DLL/SO boundaries? Would `callable_container<Func>`, for the same =
`Func` type, have different sizes on different sides of the DLL/SO? After a=
ll, object sizes are static properties; they cannot change based on which l=
ibraries are loaded. So how does that work?<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/b271154f-88f6-481b-80ea-0a228492a129%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b271154f-88f6-481b-80ea-0a228492a129=
%40isocpp.org</a>.<br />
------=_Part_1196_1399500879.1547410472467--
------=_Part_1195_1388654204.1547410472466--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Mon, 14 Jan 2019 09:36:11 -0800 (PST)
Raw View
------=_Part_1625_765448163.1547487371211
Content-Type: multipart/alternative;
boundary="----=_Part_1626_346608934.1547487371212"
------=_Part_1626_346608934.1547487371212
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Sunday, January 13, 2019 at 3:36:52 AM UTC-5, phdsch...@outlook.com=20
wrote:
>
> Hi,
>
> Many times we create a variable from a specific instantiation of a class=
=20
> template, but then need to assign a value from a different instantiation.=
=20
> This is the classic case of mixing custom allocators for standard=20
> containers with the default allocator. C++17 solves this through=20
> polymorphic memory resources. But it would be nice to have an easy soluti=
on=20
> available for programmers. Generally, the 'type erasure' pattern involves=
=20
> the use of:
>
> 1. boost/std any - which is inefficient because of the need to query the=
=20
> object or it forces use of the visitor pattern which scatters the logic a=
ll=20
> over the place.
> 2. A custom abstract interface - which leads to runtime memory allocation=
..
>
> It would be nice if there was a mechanism by which the compiler could [..=
..]
>
I think your question/proposal is based on a misunderstanding. Your "#1"=
=20
and "#2" are actually the same thing, because boost::any and std::any (#1)=
=20
are actually library types that work by using type erasure (#2). And type=
=20
erasure doesn't have to involve dynamic (heap) memory allocation. Heap=20
allocation is needed only for two non-mutually-exclusive reasons which are=
=20
really one reason:
- To indirectly store a wrapped object whose size is larger than the=20
wrapper type's SBO capacity.
- To indirectly store a wrapped object which would otherwise violate some=
=20
requirement of the wrapper, such as "trivially relocatable" or "nothrow=20
move-constructible".
Furthermore, you make an analogy to std::pmr::polymorphic_allocator =E2=80=
=94 a=20
*non-owning* handle type. If you eliminate the requirement for ownership,=
=20
then you eliminate the requirement to store a copy of the wrapped object,=
=20
which usually eliminates both reasons above. So a non-owning type-erased=20
wrapper generally doesn't allocate either.
For an example of a type-erasing, non-owning wrapper with no heap=20
allocation, see std::function_ref<Sig>=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0792r3.html>.
For an example of a type-erasing, owning wrapper with no heap allocation=20
(but a maximum SBO capacity), see stdext::inplace_function<Sig, Cap, Align>=
=20
<https://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h>.
----
As Nicol correctly states, you cannot have a type whose size is determined=
=20
only at link-time.
However, for your use-case, all you have to do is pull the SBO size out=20
into a compile-time macro:
using HandlerType =3D stdext::inplace_function<int(int),=20
HANDLER_SBO_SIZE>;
and then build your project with -DHANDLER_SBO_SIZE=3D16,=20
-DHANDLER_SBO_SIZE=3D24, -DHANDLER_SBO_SIZE=3D32, -DHANDLER_SBO_SIZE=3D40,.=
...=20
until you find a value that lets the entire project compile cleanly. Then=
=20
you can put that -D flag into your Makefile and you'll be good to go.=20
(Until some maintainer adds an even larger lambda. Then you'll have to=20
decide whether it's worth the performance penalty to increase=20
HANDLER_SBO_SIZE, or whether you should just refactor the new lambda to be=
=20
smaller.)
=E2=80=93Arthur
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ad85680f-68e5-4791-9625-ffa4b085874e%40isocpp.or=
g.
------=_Part_1626_346608934.1547487371212
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, January 13, 2019 at 3:36:52 AM UTC-5, phdsch...=
@outlook.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div>Hi,</div><div><br></div><div>Many times we create a variable fro=
m a specific instantiation of a class template, but then need to assign a v=
alue from a different instantiation. This is the classic case of mixing cus=
tom allocators for standard containers with the default allocator. C++17 so=
lves this through polymorphic memory resources. But it would be nice to hav=
e an easy solution available for programmers. Generally, the 'type eras=
ure' pattern involves the use of:</div><div><br></div><div>1. boost/std=
any - which is inefficient because of the need to query the object or it f=
orces use of the visitor pattern which scatters the logic all over the plac=
e.</div><div>2. A custom abstract interface - which leads to runtime memory=
allocation.</div><div><br></div><div>It would be nice if there was a mecha=
nism by which the compiler could [...]</div></div></blockquote><div><br></d=
iv><div>I think your question/proposal is based on a misunderstanding. =C2=
=A0Your "#1" and "#2" are actually the same thing, beca=
use boost::any and std::any (#1) are actually library types that work by us=
ing type erasure (#2). =C2=A0And type erasure doesn't have to involve d=
ynamic (heap) memory allocation. Heap allocation is needed only for two non=
-mutually-exclusive reasons which are really one reason:</div><div>- To ind=
irectly store a wrapped object whose size is larger than the wrapper type&#=
39;s SBO capacity.</div><div>- To indirectly store a wrapped object which w=
ould otherwise violate some requirement of the wrapper, such as "trivi=
ally relocatable" or "nothrow move-constructible".</div><div=
><br></div><div>Furthermore, you make an analogy to std::pmr::polymorphic_a=
llocator =E2=80=94 a=C2=A0<i>non-owning</i> handle type. If you eliminate t=
he requirement for ownership, then you eliminate the requirement to store a=
copy of the wrapped object, which usually eliminates both reasons above. S=
o a non-owning type-erased wrapper generally doesn't allocate either.</=
div><div><br></div><div>For an example of a type-erasing, non-owning wrappe=
r with no heap allocation, see <a href=3D"http://www.open-std.org/jtc1/sc22=
/wg21/docs/papers/2018/p0792r3.html">std::function_ref<Sig></a>.</div=
><div>For an example of a type-erasing, owning wrapper with no heap allocat=
ion (but a maximum SBO capacity), see <a href=3D"https://github.com/WG21-SG=
14/SG14/blob/master/SG14/inplace_function.h">stdext::inplace_function<Si=
g, Cap, Align></a>.</div><div><br></div><div>----</div><div><br></div><d=
iv>As Nicol correctly states, you cannot have a type whose size is determin=
ed only at link-time.</div><div>However, for your use-case, all you have to=
do is pull the SBO size out into a compile-time macro:</div><div><br></div=
><div>=C2=A0 =C2=A0 using HandlerType =3D stdext::inplace_function<int(i=
nt), HANDLER_SBO_SIZE>;</div><div><br></div><div>and then build your pro=
ject with -DHANDLER_SBO_SIZE=3D16, -DHANDLER_SBO_SIZE=3D24, -DHANDLER_SBO_S=
IZE=3D32, -DHANDLER_SBO_SIZE=3D40,... until you find a value that lets the =
entire project compile cleanly. Then you can put that -D flag into your Mak=
efile and you'll be good to go. (Until some maintainer adds an even lar=
ger lambda. Then you'll have to decide whether it's worth the perfo=
rmance penalty to increase HANDLER_SBO_SIZE, or whether you should just ref=
actor the new lambda to be smaller.)</div><div><br></div><div>=E2=80=93Arth=
ur</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/ad85680f-68e5-4791-9625-ffa4b085874e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ad85680f-68e5-4791-9625-ffa4b085874e=
%40isocpp.org</a>.<br />
------=_Part_1626_346608934.1547487371212--
------=_Part_1625_765448163.1547487371211--
.
Author: phdscholar80@outlook.com
Date: Tue, 22 Jan 2019 06:06:11 -0800 (PST)
Raw View
------=_Part_2614_2017997175.1548165971196
Content-Type: multipart/alternative;
boundary="----=_Part_2615_1520194664.1548165971197"
------=_Part_2615_1520194664.1548165971197
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Hi Arthur,
Many thanks for your insightful reply. Having thought more about this, I=20
really like the idea of a non-owning function wrapper. And I still insist=
=20
on not having to perform the skulduggery of figuring out the right small=20
buffer size. I want C++ code to be clean and expressive, reflecting the=20
programmer's intent and automatically translating to efficient=20
implementation. So, I would like to propose the following:
For class methods defined inside the class declaration, allow a way to=20
declare method local variables as class member variables. Thus, they have=
=20
storage within each object of the class, and can be safely passed as a type=
=20
erased reference. The size of the class includes enough aligned space for=
=20
storing these variables.
If you have the time, could you please take a look at this hypothetical=20
code?
https://github.com/amir-ahmed-ansari/bits-n-pieces/blob/lambda-erasure/lamb=
da-erasure.cpp
I know that the upcoming coroutines feature allows cleaner expression in=20
this particular case, but this is only an example. There are many places=20
where this could be useful. With libraries such as Boost.Hana and rxcpp, we=
=20
are increasingly seeing instances were the actual type is not known in=20
advance. All we have is the return value from a function call. Persisting=
=20
such objects without the need for dynamic memory allocation should be=20
possible.
Regards,
- Amir
On Tuesday, 15 January 2019 04:36:11 UTC+11, Arthur O'Dwyer wrote:
> On Sunday, January 13, 2019 at 3:36:52 AM UTC-5, phdsch...@outlook.com=20
> wrote:
>>
>> Hi,
>>
>> Many times we create a variable from a specific instantiation of a class=
=20
>> template, but then need to assign a value from a different instantiation=
..=20
>> This is the classic case of mixing custom allocators for standard=20
>> containers with the default allocator. C++17 solves this through=20
>> polymorphic memory resources. But it would be nice to have an easy solut=
ion=20
>> available for programmers. Generally, the 'type erasure' pattern involve=
s=20
>> the use of:
>>
>> 1. boost/std any - which is inefficient because of the need to query the=
=20
>> object or it forces use of the visitor pattern which scatters the logic =
all=20
>> over the place.
>> 2. A custom abstract interface - which leads to runtime memory allocatio=
n.
>>
>> It would be nice if there was a mechanism by which the compiler could=20
>> [...]
>>
>
> I think your question/proposal is based on a misunderstanding. Your "#1"=
=20
> and "#2" are actually the same thing, because boost::any and std::any (#1=
)=20
> are actually library types that work by using type erasure (#2). And typ=
e=20
> erasure doesn't have to involve dynamic (heap) memory allocation. Heap=20
> allocation is needed only for two non-mutually-exclusive reasons which ar=
e=20
> really one reason:
> - To indirectly store a wrapped object whose size is larger than the=20
> wrapper type's SBO capacity.
> - To indirectly store a wrapped object which would otherwise violate some=
=20
> requirement of the wrapper, such as "trivially relocatable" or "nothrow=
=20
> move-constructible".
>
> Furthermore, you make an analogy to std::pmr::polymorphic_allocator =E2=
=80=94 a=20
> *non-owning* handle type. If you eliminate the requirement for ownership,=
=20
> then you eliminate the requirement to store a copy of the wrapped object,=
=20
> which usually eliminates both reasons above. So a non-owning type-erased=
=20
> wrapper generally doesn't allocate either.
>
> For an example of a type-erasing, non-owning wrapper with no heap=20
> allocation, see std::function_ref<Sig>=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0792r3.html>.
> For an example of a type-erasing, owning wrapper with no heap allocation=
=20
> (but a maximum SBO capacity), see stdext::inplace_function<Sig, Cap,=20
> Align>=20
> <https://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h>.
>
> ----
>
> As Nicol correctly states, you cannot have a type whose size is determine=
d=20
> only at link-time.
> However, for your use-case, all you have to do is pull the SBO size out=
=20
> into a compile-time macro:
>
> using HandlerType =3D stdext::inplace_function<int(int),=20
> HANDLER_SBO_SIZE>;
>
> and then build your project with -DHANDLER_SBO_SIZE=3D16,=20
> -DHANDLER_SBO_SIZE=3D24, -DHANDLER_SBO_SIZE=3D32, -DHANDLER_SBO_SIZE=3D40=
,...=20
> until you find a value that lets the entire project compile cleanly. Then=
=20
> you can put that -D flag into your Makefile and you'll be good to go.=20
> (Until some maintainer adds an even larger lambda. Then you'll have to=20
> decide whether it's worth the performance penalty to increase=20
> HANDLER_SBO_SIZE, or whether you should just refactor the new lambda to b=
e=20
> smaller.)
>
> =E2=80=93Arthur
>
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/534c8ca1-db2c-453f-9f90-4d37a034173a%40isocpp.or=
g.
------=_Part_2615_1520194664.1548165971197
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hi Arthur,</div><div><br></div><div>Many thanks for y=
our insightful reply. Having thought more about this, I really like the ide=
a of a non-owning function wrapper. And I still insist on not having to per=
form the skulduggery of figuring out the right small buffer size. I want C+=
+ code to be clean and expressive, reflecting the programmer's intent a=
nd automatically translating to efficient implementation. So, I would like =
to propose the following:</div><div><br></div><div>For class methods define=
d inside the class declaration, allow a way to declare method local variabl=
es as class member variables. Thus, they have storage within each object of=
the class, and can be safely passed as a type erased reference. The size o=
f the class includes enough aligned space for storing these variables.</div=
><div><br></div><div>If you have the time, could you please take a look at =
this hypothetical code?</div><div><br></div><div>https://github.com/amir-ah=
med-ansari/bits-n-pieces/blob/lambda-erasure/lambda-erasure.cpp<br></div><d=
iv><br></div><div>I know that the upcoming coroutines feature allows cleane=
r expression in this particular case, but this is only an example. There ar=
e many places where this could be useful. With libraries such as Boost.Hana=
and rxcpp, we are increasingly seeing instances were the actual type is no=
t known in advance. All we have is the return value from a function call. P=
ersisting such objects without the need for dynamic memory allocation shoul=
d be possible.</div><div><br></div><div>Regards,</div><div><br></div><div>-=
Amir</div><div><br></div><div>On Tuesday, 15 January 2019 04:36:11 UTC+11,=
Arthur O'Dwyer wrote:</div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">On Sunday, January 13, 2019 at 3:36:52 AM UTC-5, <a>phd=
sch...@outlook.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div>Hi,</div><div><br></div><div>Many times we create a variabl=
e from a specific instantiation of a class template, but then need to assig=
n a value from a different instantiation. This is the classic case of mixin=
g custom allocators for standard containers with the default allocator. C++=
17 solves this through polymorphic memory resources. But it would be nice t=
o have an easy solution available for programmers. Generally, the 'type=
erasure' pattern involves the use of:</div><div><br></div><div>1. boos=
t/std any - which is inefficient because of the need to query the object or=
it forces use of the visitor pattern which scatters the logic all over the=
place.</div><div>2. A custom abstract interface - which leads to runtime m=
emory allocation.</div><div><br></div><div>It would be nice if there was a =
mechanism by which the compiler could [...]</div></div></blockquote><div><b=
r></div><div>I think your question/proposal is based on a misunderstanding.=
=C2=A0Your "#1" and "#2" are actually the same thing, =
because boost::any and std::any (#1) are actually library types that work b=
y using type erasure (#2). =C2=A0And type erasure doesn't have to invol=
ve dynamic (heap) memory allocation. Heap allocation is needed only for two=
non-mutually-exclusive reasons which are really one reason:</div><div>- To=
indirectly store a wrapped object whose size is larger than the wrapper ty=
pe's SBO capacity.</div><div>- To indirectly store a wrapped object whi=
ch would otherwise violate some requirement of the wrapper, such as "t=
rivially relocatable" or "nothrow move-constructible".</div>=
<div><br></div><div>Furthermore, you make an analogy to std::pmr::polymorph=
ic_<wbr>allocator =E2=80=94 a=C2=A0<i>non-owning</i> handle type. If you el=
iminate the requirement for ownership, then you eliminate the requirement t=
o store a copy of the wrapped object, which usually eliminates both reasons=
above. So a non-owning type-erased wrapper generally doesn't allocate =
either.</div><div><br></div><div>For an example of a type-erasing, non-owni=
ng wrapper with no heap allocation, see <a onmousedown=3D"this.href=3D'=
http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%=
2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp0792r3.html\x26sa\x3dD\x26sntz\x3d1\x26usg=
\x3dAFQjCNFYNaNti3c7SUAe9983KOOzE_k14g';return true;" onclick=3D"this.h=
ref=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fj=
tc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp0792r3.html\x26sa\x3dD\x26sntz\=
x3d1\x26usg\x3dAFQjCNFYNaNti3c7SUAe9983KOOzE_k14g';return true;" href=
=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0792r3.html" t=
arget=3D"_blank" rel=3D"nofollow">std::function_ref<Sig></a>.</div><d=
iv>For an example of a type-erasing, owning wrapper with no heap allocation=
(but a maximum SBO capacity), see <a onmousedown=3D"this.href=3D'https=
://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FWG21-SG14%2FSG14%2Fbl=
ob%2Fmaster%2FSG14%2Finplace_function.h\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNGWex35dzi6es2jTmGdKPw9asRYXQ';return true;" onclick=3D"this.href=
=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FWG21-SG1=
4%2FSG14%2Fblob%2Fmaster%2FSG14%2Finplace_function.h\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNGWex35dzi6es2jTmGdKPw9asRYXQ';return true;" href=3D"h=
ttps://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h" targe=
t=3D"_blank" rel=3D"nofollow">stdext::inplace_function<Sig, Cap, Align&g=
t;</a>.</div><div><br></div><div>----</div><div><br></div><div>As Nicol cor=
rectly states, you cannot have a type whose size is determined only at link=
-time.</div><div>However, for your use-case, all you have to do is pull the=
SBO size out into a compile-time macro:</div><div><br></div><div>=C2=A0 =
=C2=A0 using HandlerType =3D stdext::inplace_function<int(<wbr>int), HAN=
DLER_SBO_SIZE>;</div><div><br></div><div>and then build your project wit=
h -DHANDLER_SBO_SIZE=3D16, -DHANDLER_SBO_SIZE=3D24, -DHANDLER_SBO_SIZE=3D32=
, -DHANDLER_SBO_SIZE=3D40,... until you find a value that lets the entire p=
roject compile cleanly. Then you can put that -D flag into your Makefile an=
d you'll be good to go. (Until some maintainer adds an even larger lamb=
da. Then you'll have to decide whether it's worth the performance p=
enalty to increase HANDLER_SBO_SIZE, or whether you should just refactor th=
e new lambda to be smaller.)</div><div><br></div><div>=E2=80=93Arthur</div>=
</div></blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/534c8ca1-db2c-453f-9f90-4d37a034173a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/534c8ca1-db2c-453f-9f90-4d37a034173a=
%40isocpp.org</a>.<br />
------=_Part_2615_1520194664.1548165971197--
------=_Part_2614_2017997175.1548165971196--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 22 Jan 2019 10:38:52 -0500
Raw View
--0000000000006381bd05800dc64e
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Tue, Jan 22, 2019 at 9:06 AM <phdscholar80@outlook.com> wrote:
> Hi Arthur,
>
> Many thanks for your insightful reply. Having thought more about this, I
> really like the idea of a non-owning function wrapper. And I still insist
> on not having to perform the skulduggery of figuring out the right small
> buffer size. I want C++ code to be clean and expressive, reflecting the
> programmer's intent and automatically translating to efficient
> implementation. So, I would like to propose the following:
>
> For class methods defined inside the class declaration, allow a way to
> declare method local variables as class member variables. Thus, they have
> storage within each object of the class, and can be safely passed as a ty=
pe
> erased reference. The size of the class includes enough aligned space for
> storing these variables.
>
> If you have the time, could you please take a look at this hypothetical
> code?
>
>
> https://github.com/amir-ahmed-ansari/bits-n-pieces/blob/lambda-erasure/la=
mbda-erasure.cpp
>
Okay, I've looked.
Have *you* looked at `function_ref`? It seems to be exactly what you're
trying to do, but by looking at a real implementation you can find out how
it's implemented.
> I know that the upcoming coroutines feature allows cleaner expression in
> this particular case
>
No, it doesn't. Coroutines doesn't have anything to do with either
type-erasure or vocabulary types for functions.
> , but this is only an example. There are many places where this could be
> useful. With libraries such as Boost.Hana and rxcpp, we are increasingly
> seeing instances were the actual type is not known in advance. All we hav=
e
> is the return value from a function call. Persisting such objects without
> the need for dynamic memory allocation should be possible.
>
It is possible. Look at inplace_function or function_ref.
=E2=80=93Arthur
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0%2BJnpXSedfw8Sjcd5CQZ5jF9mfu76MXA%2BdvNZ6=
heRUiXw%40mail.gmail.com.
--0000000000006381bd05800dc64e
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr">On Tue, Jan 22, 2019 at 9:06 AM <<a hr=
ef=3D"mailto:phdscholar80@outlook.com">phdscholar80@outlook.com</a>> wro=
te:<br></div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:so=
lid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><=
div>Hi Arthur,</div><div><br></div><div>Many thanks for your insightful rep=
ly. Having thought more about this, I really like the idea of a non-owning =
function wrapper. And I still insist on not having to perform the skuldugge=
ry of figuring out the right small buffer size. I want C++ code to be clean=
and expressive, reflecting the programmer's intent and automatically t=
ranslating to efficient implementation. So, I would like to propose the fol=
lowing:</div><div><br></div><div>For class methods defined inside the class=
declaration, allow a way to declare method local variables as class member=
variables. Thus, they have storage within each object of the class, and ca=
n be safely passed as a type erased reference. The size of the class includ=
es enough aligned space for storing these variables.</div><div><br></div><d=
iv>If you have the time, could you please take a look at this hypothetical =
code?</div><div><br></div><div><a href=3D"https://github.com/amir-ahmed-ans=
ari/bits-n-pieces/blob/lambda-erasure/lambda-erasure.cpp" target=3D"_blank"=
>https://github.com/amir-ahmed-ansari/bits-n-pieces/blob/lambda-erasure/lam=
bda-erasure.cpp</a></div></div></blockquote><div><br></div><div>Okay, I'=
;ve looked.</div><div>Have <i>you</i> looked at `function_ref`? It seems to=
be exactly what you're trying to do, but by looking at a real implemen=
tation you can find out how it's implemented.</div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr"><div></div><div>I know that the upcoming cor=
outines feature allows cleaner expression in this particular case</div></di=
v></blockquote><div><br></div><div>No, it doesn't. Coroutines doesn'=
;t have anything to do with either type-erasure or vocabulary types for fun=
ctions.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border=
-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>, but =
this is only an example. There are many places where this could be useful. =
With libraries such as Boost.Hana and rxcpp, we are increasingly seeing ins=
tances were the actual type is not known in advance. All we have is the ret=
urn value from a function call. Persisting such objects without the need fo=
r dynamic memory allocation should be possible.</div></div></blockquote><di=
v><br></div><div>It is possible. Look at inplace_function or function_ref.<=
/div><div><br></div><div>=E2=80=93Arthur</div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CADvuK0%2BJnpXSedfw8Sjcd5CQZ5jF9mfu76=
MXA%2BdvNZ6heRUiXw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BJnp=
XSedfw8Sjcd5CQZ5jF9mfu76MXA%2BdvNZ6heRUiXw%40mail.gmail.com</a>.<br />
--0000000000006381bd05800dc64e--
.