Topic: any vs. CopyConstructible
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Tue, 19 Apr 2016 04:58:31 -0700 (PDT)
Raw View
------=_Part_5282_1437183079.1461067111656
Content-Type: multipart/alternative;
boundary="----=_Part_5283_217265476.1461067111656"
------=_Part_5283_217265476.1461067111656
Content-Type: text/plain; charset=UTF-8
Currently std::any can't be initialized by a value of noncopyable type
through the constructor template because [any.cons]/7 explicitly renders it
ill-formed. Is this intended by design?
As I know, some type erasure stuff in boost does not handle noncopyable
type at all. The reason seems to be just the limitation of the core
language then.
I think it will be useful to allow noncopyable values in the constructor
template, e.g. to store type-erased scope guard objects directly (as return
type, etc) which can be specified at runtime (this can be work around by
shared_ptr<void> or unique_ptr<any>, but obviously uglier than needed).
Though to make the noncopyable types work, the specification of copy
constructor may need some changes, e.g. throwing on copying a noncopyable
contained object.
Like std::optional, std::any can also have "in place" constructors (for
each target type from template argument of the constructor template) to
enable "emplace" and bypass some unneeded copy construction.
I have tested these extensions in my code base so I am sure they are
implementable. Any further ideas?
--
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/9d1d5658-5d9d-472f-b2b6-c3bd1380062d%40isocpp.org.
------=_Part_5283_217265476.1461067111656
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Currently std::any can't be initialized by a value of =
noncopyable type through the constructor template because [any.cons]/7 expl=
icitly renders it ill-formed. Is this intended by design?<br><br>As I know,=
some type erasure stuff in boost does not handle noncopyable type at all. =
The reason seems to be just the limitation of the core language then.<br><b=
r>I think it will be useful to allow noncopyable values in the constructor =
template, e.g. to store type-erased scope guard objects directly (as return=
type, etc) which can be specified at runtime (this can be work around by s=
hared_ptr<void> or unique_ptr<any>, but obviously uglier than n=
eeded). Though to make the noncopyable types work, the specification of cop=
y constructor may need some changes, e.g. throwing on copying a noncopyable=
contained object.<br><br>Like std::optional, std::any can also have "=
in place" constructors (for each target type from template argument of=
the constructor template) to enable "emplace" and bypass some un=
needed copy construction.<br><br>I have tested these extensions in my code =
base so I am sure they are implementable. Any further ideas?<br><br></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/9d1d5658-5d9d-472f-b2b6-c3bd1380062d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9d1d5658-5d9d-472f-b2b6-c3bd1380062d=
%40isocpp.org</a>.<br />
------=_Part_5283_217265476.1461067111656--
------=_Part_5282_1437183079.1461067111656--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 19 Apr 2016 15:08:50 +0300
Raw View
On 19 April 2016 at 14:58, FrankHB1989 <frankhb1989@gmail.com> wrote:
> Currently std::any can't be initialized by a value of noncopyable type
> through the constructor template because [any.cons]/7 explicitly renders it
> ill-formed. Is this intended by design?
Yes, because attempts to copy the resulting any would need to always throw.
That seems undesirable and viral.
--
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/CAFk2RUZdn69VXGOXCH%3DUrCavs6v%2B_1jMcEcK-%2B1gZRvCq2ONpg%40mail.gmail.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Apr 2016 08:50:18 -0700 (PDT)
Raw View
------=_Part_2585_1560902192.1461081018841
Content-Type: multipart/alternative;
boundary="----=_Part_2586_1593562029.1461081018841"
------=_Part_2586_1593562029.1461081018841
Content-Type: text/plain; charset=UTF-8
On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrote:
>
> On 19 April 2016 at 14:58, FrankHB1989 <frank...@gmail.com <javascript:>>
> wrote:
> > Currently std::any can't be initialized by a value of noncopyable type
> > through the constructor template because [any.cons]/7 explicitly renders
> it
> > ill-formed. Is this intended by design?
>
> Yes, because attempts to copy the resulting any would need to always
> throw.
> That seems undesirable and viral.
>
Agreed. Every `any` instance should have the same behavior, outside of an
`any_cast`.
If you need the type-hiding effects of `any`, but allowing for non-copyable
types, then this should be a *different* type. Perhaps `unique_any`. There
could even be some interop between the two types, with `any` being
convertible to a `unique_any` (but obviously not vice-versa).
--
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/a0724368-a991-44de-b353-f5e9fed5f210%40isocpp.org.
------=_Part_2586_1593562029.1461081018841
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Vi=
lle Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 19 Ap=
ril 2016 at 14:58, FrankHB1989 <<a href=3D"javascript:" target=3D"_blank=
" gdf-obfuscated-mailto=3D"1PIJsDrvBQAJ" rel=3D"nofollow" onmousedown=3D"th=
is.href=3D'javascript:';return true;" onclick=3D"this.href=3D'j=
avascript:';return true;">frank...@gmail.com</a>> wrote:
<br>> Currently std::any can't be initialized by a value of noncopya=
ble type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<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/a0724368-a991-44de-b353-f5e9fed5f210%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a0724368-a991-44de-b353-f5e9fed5f210=
%40isocpp.org</a>.<br />
------=_Part_2586_1593562029.1461081018841--
------=_Part_2585_1560902192.1461081018841--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Tue, 19 Apr 2016 12:05:16 -0700 (PDT)
Raw View
------=_Part_2646_1129694139.1461092717259
Content-Type: multipart/alternative;
boundary="----=_Part_2647_1900459886.1461092717266"
------=_Part_2647_1900459886.1461092717266
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=8C UTC=
+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
>
>
> On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrote:
>>
>> On 19 April 2016 at 14:58, FrankHB1989 <frank...@gmail.com> wrote:=20
>> > Currently std::any can't be initialized by a value of noncopyable type=
=20
>> > through the constructor template because [any.cons]/7 explicitly=20
>> renders it=20
>> > ill-formed. Is this intended by design?=20
>>
>> Yes, because attempts to copy the resulting any would need to always=20
>> throw.=20
>> That seems undesirable and viral.=20
>>
>
> Agreed. Every `any` instance should have the same behavior, outside of an=
=20
> `any_cast`.
>
> If you need the type-hiding effects of `any`, but allowing for=20
> non-copyable types, then this should be a *different* type. Perhaps=20
> `unique_any`. There could even be some interop between the two types, wit=
h=20
> `any` being convertible to a `unique_any` (but obviously not vice-versa).
>
Well, I agree that they should be different types for the purpose of static=
=20
type checking.
However, literally it is strange to constraint the contained type of "any"=
=20
rather than of "any_copyable".
Perhaps I need one more "unique_any", and then there can be "variant<any,=
=20
unique_any>"... But wait, even this approach has the similar semantic noise=
=20
because here "any" and "unique_any" are still nullable types which may be=
=20
probably not needed. If "any" is not nullable (which is more friendly to=20
clarity, performance and type check), strictly speaking it should be=20
"variant<optional<any>, optional<unique_any>>"... oh should I really afford=
=20
the complexity like this (esp. "optional" may be not optimal here unless=20
specialized)? Also note the latter is about trade off between correctness=
=20
vs. simpleness, but the former is concerned with *functionality*. And if I=
=20
should indeed write one new "unique_any", there is also a minor issue: it=
=20
can hardly share implementation with "std::any", which may lead to=20
unnecessary code bloat.
BTW, for some other types, the state of default-initialized value is also=
=20
redundant and may be not needed. For example, call of operator() of a=20
std::function instance needs to check for "std::bad_function_call" even the=
=20
user can make sure there is always a target in the wrapper. Is this desired=
?
=20
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d1140491-d050-4e83-8cfe-fe5a4924681f%40isocpp.or=
g.
------=_Part_2647_1900459886.1461092717266
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=BA=8C UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=
=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><br><br>On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville=
Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 19 April 2016=
at 14:58, FrankHB1989 <<a rel=3D"nofollow">frank...@gmail.com</a>> w=
rote:
<br>> Currently std::any can't be initialized by a value of noncopya=
ble type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<br></div></div></blockquote><div><br>Well, I a=
gree that they should be different types for the purpose of static type che=
cking.<br><br>However, literally it is strange to constraint the contained =
type of "any" rather than of "any_copyable".<br><br>Per=
haps I need one more "unique_any", and then there can be "va=
riant<any, unique_any>"... But wait, even this approach has the =
similar semantic noise because here "any" and "unique_any&qu=
ot; are still nullable types which may be probably not needed. If "any=
" is not nullable (which is more friendly to clarity, performance and =
type check), strictly speaking it should be "variant<optional<an=
y>, optional<unique_any>>"... oh should I really afford th=
e complexity like this (esp. "optional" may be not optimal here u=
nless specialized)? Also note the latter is about trade off between correct=
ness vs. simpleness, but the former is concerned with <i>functionality</i>.=
And if I should indeed write one new "unique_any", there is also=
a minor issue: it can hardly share implementation with "std::any"=
;, which may lead to unnecessary code bloat.<br><br>BTW, for some other typ=
es, the state of default-initialized value is also redundant and may be not=
needed. For example, call of operator() of a std::function instance needs =
to check for "std::bad_function_call" even the user can make sure=
there is always a target in the wrapper. Is this desired?<br><br><br><br><=
br><br>=C2=A0<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/d1140491-d050-4e83-8cfe-fe5a4924681f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d1140491-d050-4e83-8cfe-fe5a4924681f=
%40isocpp.org</a>.<br />
------=_Part_2647_1900459886.1461092717266--
------=_Part_2646_1129694139.1461092717259--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 Apr 2016 13:57:45 -0700 (PDT)
Raw View
------=_Part_590_2074471204.1461099465662
Content-Type: multipart/alternative;
boundary="----=_Part_591_1153874619.1461099465662"
------=_Part_591_1153874619.1461099465662
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, April 19, 2016 at 3:05:17 PM UTC-4, FrankHB1989 wrote:
>
>
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=8C U=
TC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>>
>>
>> On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrote:
>>>
>>> On 19 April 2016 at 14:58, FrankHB1989 <frank...@gmail.com> wrote:=20
>>> > Currently std::any can't be initialized by a value of noncopyable typ=
e=20
>>> > through the constructor template because [any.cons]/7 explicitly=20
>>> renders it=20
>>> > ill-formed. Is this intended by design?=20
>>>
>>> Yes, because attempts to copy the resulting any would need to always=20
>>> throw.=20
>>> That seems undesirable and viral.=20
>>>
>>
>> Agreed. Every `any` instance should have the same behavior, outside of a=
n=20
>> `any_cast`.
>>
>> If you need the type-hiding effects of `any`, but allowing for=20
>> non-copyable types, then this should be a *different* type. Perhaps=20
>> `unique_any`. There could even be some interop between the two types, wi=
th=20
>> `any` being convertible to a `unique_any` (but obviously not vice-versa)=
..
>>
>
> Well, I agree that they should be different types for the purpose of=20
> static type checking.
>
> However, literally it is strange to constraint the contained type of "any=
"=20
> rather than of "any_copyable".
>
> Perhaps I need one more "unique_any", and then there can be "variant<any,=
=20
> unique_any>"
>
How will that help? `unique_any` is non-copyable. And if a `variant`=20
contains any type that is non-copyable, the variant itself is non-copyable.=
=20
Same goes for `optional`.
So you've accomplished nothing more than just using `unique_any` directly.
It's not clear what exactly you want here. You want a type which can store=
=20
anything. But you don't seem to want it to be a *value* type. Because=20
that's what makes `any` require the type to be copyable. The closest you're=
=20
going to get to that is `shared_ptr<unique_any>`: a memory-safe reference=
=20
type to a possibly-non-copyable value that could store any type.
--=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/be332026-ab47-42bd-9aff-4c39455c0e36%40isocpp.or=
g.
------=_Part_591_1153874619.1461099465662
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, April 19, 2016 at 3:05:17 PM UTC-4, Fr=
ankHB1989 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=
=E4=BA=8C UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=
=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br=
><br>On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex">On 19 April 2016 at 14:58, FrankH=
B1989 <<a rel=3D"nofollow">frank...@gmail.com</a>> wrote:
<br>> Currently std::any can't be initialized by a value of noncopya=
ble type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<br></div></div></blockquote><div><br>Well, I a=
gree that they should be different types for the purpose of static type che=
cking.<br><br>However, literally it is strange to constraint the contained =
type of "any" rather than of "any_copyable".<br><br>Per=
haps I need one more "unique_any", and then there can be "va=
riant<any, unique_any>"</div></div></blockquote><div><br>How wil=
l that help? `unique_any` is non-copyable. And if a `variant` contains any =
type that is non-copyable, the variant itself is non-copyable. Same goes fo=
r `optional`.<br><br>So you've accomplished nothing more than just usin=
g `unique_any` directly.<br><br>It's not clear what exactly you want he=
re. You want a type which can store anything. But you don't seem to wan=
t it to be a <i>value</i> type. Because that's what makes `any` require=
the type to be copyable. The closest you're going to get to that is `s=
hared_ptr<unique_any>`: a memory-safe reference type to a possibly-no=
n-copyable value that could store any type.</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/be332026-ab47-42bd-9aff-4c39455c0e36%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/be332026-ab47-42bd-9aff-4c39455c0e36=
%40isocpp.org</a>.<br />
------=_Part_591_1153874619.1461099465662--
------=_Part_590_2074471204.1461099465662--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Tue, 19 Apr 2016 18:44:26 -0700 (PDT)
Raw View
------=_Part_2797_504891057.1461116666304
Content-Type: multipart/alternative;
boundary="----=_Part_2798_23418996.1461116666305"
------=_Part_2798_23418996.1461116666305
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC=
+8=E4=B8=8A=E5=8D=884:57:45=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
>
>
> On Tuesday, April 19, 2016 at 3:05:17 PM UTC-4, FrankHB1989 wrote:
>>
>>
>>
>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=8C =
UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>>
>>>
>>>
>>> On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrote=
:
>>>>
>>>> On 19 April 2016 at 14:58, FrankHB1989 <frank...@gmail.com> wrote:=20
>>>> > Currently std::any can't be initialized by a value of noncopyable=20
>>>> type=20
>>>> > through the constructor template because [any.cons]/7 explicitly=20
>>>> renders it=20
>>>> > ill-formed. Is this intended by design?=20
>>>>
>>>> Yes, because attempts to copy the resulting any would need to always=
=20
>>>> throw.=20
>>>> That seems undesirable and viral.=20
>>>>
>>>
>>> Agreed. Every `any` instance should have the same behavior, outside of=
=20
>>> an `any_cast`.
>>>
>>> If you need the type-hiding effects of `any`, but allowing for=20
>>> non-copyable types, then this should be a *different* type. Perhaps=20
>>> `unique_any`. There could even be some interop between the two types, w=
ith=20
>>> `any` being convertible to a `unique_any` (but obviously not vice-versa=
).
>>>
>>
>> Well, I agree that they should be different types for the purpose of=20
>> static type checking.
>>
>> However, literally it is strange to constraint the contained type of=20
>> "any" rather than of "any_copyable".
>>
>> Perhaps I need one more "unique_any", and then there can be "variant<any=
,=20
>> unique_any>"
>>
>
> How will that help? `unique_any` is non-copyable. And if a `variant`=20
> contains any type that is non-copyable, the variant itself is non-copyabl=
e.=20
> Same goes for `optional`.
>
> So you've accomplished nothing more than just using `unique_any` directly=
..
>
> My fault. I should say it is a sum type (in type theory sense) which can=
=20
behave as either one of its component when appropriate.=20
I was partially wrong here because:
- This is not implementable in pure library way under current core=20
language rules. I'd use "__variant" rather than "variant" to make it=20
clearer.
- I didn't read your answer previous carefully enough. Actually, I came=
=20
up with the name of "unique_any" by myself several minutes after my=20
original post, and then found it is the same thing you suggested in your=
=20
answer, but I didn't notice the interop between two types. So more=20
importantly, since one can convert to other, it is not necessary to=20
implement it by a (core language based) sum type here (even the latter=
=20
should benefit in general, e.g. to replace builtin pointers).
=20
=20
> It's not clear what exactly you want here. You want a type which can stor=
e=20
> anything. But you don't seem to want it to be a *value* type. Because=20
> that's what makes `any` require the type to be copyable. The closest you'=
re=20
> going to get to that is `shared_ptr<unique_any>`: a memory-safe reference=
=20
> type to a possibly-non-copyable value that could store any type.
>
It may sound strange to deliberately not differentiate the two types=20
statically, but it does make sense in several cases. One practical reason=
=20
is compatibility, perhaps at both API/ABI level. Because type-erased type=
=20
is a useful way to hide some implementation details, it should be better=20
stable at least in public API (that API expose "any" should be somewhat=20
low-level, though). Ideally, I can delay the choice of disallowing the copy=
=20
to specific portion of client code while stay binary compatible with=20
reasonably useful functionality and reusablity. The type=20
"std::unique_ptr<std::any>" should work here, but it introduces an extra=20
level of indirection and one more hole of null state (as I mentioned, I=20
even don't want default-initialized value of "any") which is not desired.=
=20
It is also exposed as "reference type" not desired in several cases (e.g.=
=20
type-erased scope guard storage, though "unique_any" may be enough in this=
=20
specific case because copy of guards make little sense), which may lead to=
=20
confusion (though an alias will simply help). So a type with "mixed"=20
behavior is still useful.
Note the concept of "value type" or "reference type" is not of C++ language=
=20
rules, so expectation on "copyable" is not always fair. They are built in=
=20
some other languages because they are typically useful, but as said above,=
=20
an object whose static type is not exact one of "value" or "reference"=20
still plays some roles better (this can be impossible in languages which=20
differentiate "value" and "reference" explicitly in their core rules). And=
=20
even in most cases the distinction of "value" or "reference" should be=20
better kept, it is specifically not so good for the meaning of "any". The=
=20
"mixed" behavior with name "any" here is more friendly to the principle to=
=20
least astonishment.
=20
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/16c9147e-c5d1-4e89-b77d-3e2f0397c136%40isocpp.or=
g.
------=_Part_2798_23418996.1461116666305
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=8D=884:57:45=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><br><br>On Tuesday, April 19, 2016 at 3:05:17 PM UTC-4, FrankHB1=
989 wrote:<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"><br><br>=
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=8C UTC=
+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>On Tuesday=
, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex">On 19 April 2016 at 14:58, FrankHB1989 <<a re=
l=3D"nofollow">frank...@gmail.com</a>> wrote:
<br>> Currently std::any can't be initialized by a value of noncopya=
ble type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<br></div></div></blockquote><div><br>Well, I a=
gree that they should be different types for the purpose of static type che=
cking.<br><br>However, literally it is strange to constraint the contained =
type of "any" rather than of "any_copyable".<br><br>Per=
haps I need one more "unique_any", and then there can be "va=
riant<any, unique_any>"</div></div></blockquote><div><br>How wil=
l that help? `unique_any` is non-copyable. And if a `variant` contains any =
type that is non-copyable, the variant itself is non-copyable. Same goes fo=
r `optional`.<br><br>So you've accomplished nothing more than just usin=
g `unique_any` directly.<br><br></div></div></blockquote><div>My fault. I s=
hould say it is a sum type (in type theory sense) which can behave as eithe=
r one of its component when appropriate. <br><br>I was partially wrong here=
because:<br><ul><li>This is not implementable in pure library way under cu=
rrent core language rules. I'd use "__variant" rather than &q=
uot;variant" to make it clearer.</li><li>I didn't read your answer=
previous carefully enough. Actually, I came up with the name of "uniq=
ue_any" by myself several minutes after my original post, and then fou=
nd it is the same thing you suggested in your answer, but I didn't noti=
ce the interop between two types. So more importantly, since one can conver=
t to other, it is not necessary to implement it by a (core language based) =
sum type here (even the latter should benefit in general, e.g. to replace b=
uiltin pointers).<br></li></ul>=C2=A0<br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div>It's not clear what exactly you =
want here. You want a type which can store anything. But you don't seem=
to want it to be a <i>value</i> type. Because that's what makes `any` =
require the type to be copyable. The closest you're going to get to tha=
t is `shared_ptr<unique_any>`: a memory-safe reference type to a poss=
ibly-non-copyable value that could store any type.</div></div></blockquote>=
<div><br><br>It may sound strange to deliberately not differentiate the two=
types statically, but it does make sense in several cases. One practical r=
eason is compatibility, perhaps at both API/ABI level. Because type-erased =
type is a useful way to hide some implementation details, it=20
should be better stable at least in public API (that API expose "any&q=
uot; should be somewhat low-level, though). Ideally, I can delay the=20
choice of disallowing the copy to specific portion of client code while sta=
y binary
compatible with reasonably useful functionality and reusablity. The type &=
quot;std::unique_ptr<std::any>" should work=20
here, but it introduces an extra level of indirection and one more hole=20
of null state (as I mentioned, I even don't want default-initialized=20
value of "any") which is not desired. It is also exposed as "=
;reference type" not desired in several cases (e.g. type-erased scope =
guard storage, though "unique_any" may be enough in this specific=
case because copy of guards make little sense), which may lead to confusio=
n (though an alias will simply help). So a type with "mixed" beha=
vior is=20
still useful.<br><br>Note the concept of "value type" or "re=
ference type" is not of C++ language rules, so expectation on "co=
pyable" is not always fair. They are built in some other languages bec=
ause they are typically useful, but as said above, an object whose static t=
ype is not exact one of "value" or "reference" still pl=
ays some roles better (this can be impossible in languages which differenti=
ate "value" and "reference" explicitly in their core ru=
les). And even in most cases the distinction of "value" or "=
reference" should be better kept, it is specifically not so good for t=
he meaning of "any". The "mixed" behavior with name &qu=
ot;any" here is more friendly to the principle to=20
least astonishment.<br>=C2=A0<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/16c9147e-c5d1-4e89-b77d-3e2f0397c136%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/16c9147e-c5d1-4e89-b77d-3e2f0397c136=
%40isocpp.org</a>.<br />
------=_Part_2798_23418996.1461116666305--
------=_Part_2797_504891057.1461116666304--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Tue, 19 Apr 2016 19:19:49 -0700 (PDT)
Raw View
------=_Part_1629_966307814.1461118789749
Content-Type: multipart/alternative;
boundary="----=_Part_1630_490339551.1461118789749"
------=_Part_1630_490339551.1461118789749
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC=
+8=E4=B8=8A=E5=8D=889:44:26=EF=BC=8CFrankHB1989=E5=86=99=E9=81=93=EF=BC=9A
>
>
> It may sound strange to deliberately not differentiate the two types=20
> statically, but it does make sense in several cases. One practical reason=
=20
> is compatibility, perhaps at both API/ABI level. Because type-erased type=
=20
> is a useful way to hide some implementation details, it should be better=
=20
> stable at least in public API (that API expose "any" should be somewhat=
=20
> low-level, though). Ideally, I can delay the choice of disallowing the co=
py=20
> to specific portion of client code while stay binary compatible with=20
> reasonably useful functionality and reusablity. The type=20
> "std::unique_ptr<std::any>" should work here, but it introduces an extra=
=20
> level of indirection and one more hole of null state (as I mentioned, I=
=20
> even don't want default-initialized value of "any") which is not desired.=
=20
> It is also exposed as "reference type" not desired in several cases (e.g.=
=20
> type-erased scope guard storage, though "unique_any" may be enough in thi=
s=20
> specific case because copy of guards make little sense), which may lead t=
o=20
> confusion (though an alias will simply help). So a type with "mixed"=20
> behavior is still useful.
>
> =20
>
Some additional notes: I know it is bad to mix them in sense of type=20
theory, but this is a compromise. The root reason is that the language=20
provides no way to indicate that some invariants would be kept within/among=
=20
some set of nominal types (e.g. ABI compatibility attributes, mangling=20
tags, some explicit layout control...) in a portable way, *and *the usual=
=20
ways of abstraction (e.g. as data members directly) will often break these=
=20
invariants even some underlying properties (e.g. the object model related=
=20
with unary &) is not interested. (Note the object model of C++ is based on=
=20
some rules from C, which has a limited form of structural typing called=20
"compatible types" to work around several related problems, but it does not=
=20
work and exist in C++.)
To just resolve some practical problems, the topic will be too broad, so I=
=20
don't expect this right but not-so-obvious way will work immediately. On=20
the other hand, the difficulties of this solution on language=20
implementations (e.g. ABI compatibility across different versions of the=20
standard library binary images) and the difficulties of migration beyond=20
simple modification on limited portion of code (e.g. libraries without=20
source, the cost to update and test for the compiler and libraries,=20
probably needed massive rebuild, ...) effectively prevent fix on any "old"=
=20
code before the release of these implementations, so a dirty workaround=20
makes sense.
--=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/ab8d424c-0c14-4ef2-b230-62797b32d56a%40isocpp.or=
g.
------=_Part_1630_490339551.1461118789749
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=8D=889:44:26=EF=BC=8CFrankHB1989=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><br><div>It may sound strange to deliberately not differentiate =
the two types statically, but it does make sense in several cases. One prac=
tical reason is compatibility, perhaps at both API/ABI level. Because type-=
erased type is a useful way to hide some implementation details, it=20
should be better stable at least in public API (that API expose "any&q=
uot; should be somewhat low-level, though). Ideally, I can delay the=20
choice of disallowing the copy to specific portion of client code while sta=
y binary
compatible with reasonably useful functionality and reusablity. The type &=
quot;std::unique_ptr<std::any>" should work=20
here, but it introduces an extra level of indirection and one more hole=20
of null state (as I mentioned, I even don't want default-initialized=20
value of "any") which is not desired. It is also exposed as "=
;reference type" not desired in several cases (e.g. type-erased scope =
guard storage, though "unique_any" may be enough in this specific=
case because copy of guards make little sense), which may lead to confusio=
n (though an alias will simply help). So a type with "mixed" beha=
vior is=20
still useful.<br><br>=C2=A0<br></div></div></blockquote><div><br>Some addit=
ional notes: I know it is bad to mix them in sense of type theory, but this=
is a compromise. The root reason is that the language provides no way to i=
ndicate that some invariants would be kept within/among some set of nominal=
types (e.g. ABI compatibility attributes, mangling tags, some explicit lay=
out control...) in a portable way, <i>and </i>the usual ways of abstraction=
(e.g. as data members directly) will often break these invariants even som=
e underlying properties (e.g. the object model related with unary &) is=
not interested. (Note the object model of C++ is based on some rules from =
C, which has a limited form of structural typing called "compatible ty=
pes" to work around several related problems, but it does not work and=
exist in C++.)<br><br>To just resolve some practical problems, the topic w=
ill be too broad, so I don't expect this right but not-so-obvious way w=
ill work immediately. On the other hand, the difficulties of this solution =
on language implementations (e.g. ABI compatibility across different versio=
ns of the standard library binary images) and the difficulties of migration=
beyond simple modification on limited portion of code (e.g. libraries with=
out source, the cost to update and test for the compiler and libraries, pro=
bably needed massive rebuild, ...) effectively prevent fix on any "old=
" code before the release of these implementations, so a dirty workaro=
und makes sense.<br><br><br><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/ab8d424c-0c14-4ef2-b230-62797b32d56a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ab8d424c-0c14-4ef2-b230-62797b32d56a=
%40isocpp.org</a>.<br />
------=_Part_1630_490339551.1461118789749--
------=_Part_1629_966307814.1461118789749--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 20 Apr 2016 06:55:42 -0700 (PDT)
Raw View
------=_Part_13289_1448601370.1461160542542
Content-Type: multipart/alternative;
boundary="----=_Part_13290_2054224471.1461160542543"
------=_Part_13290_2054224471.1461160542543
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, April 19, 2016 at 9:44:26 PM UTC-4, FrankHB1989 wrote:
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 U=
TC+8=E4=B8=8A=E5=8D=884:57:45=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>> On Tuesday, April 19, 2016 at 3:05:17 PM UTC-4, FrankHB1989 wrote:
>>>
>>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=8C=
UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=
=BC=9A
>>>>
>>>> On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrot=
e:
>>>>>
>>>>> On 19 April 2016 at 14:58, FrankHB1989 <frank...@gmail.com> wrote:=20
>>>>> > Currently std::any can't be initialized by a value of noncopyable=
=20
>>>>> type=20
>>>>> > through the constructor template because [any.cons]/7 explicitly=20
>>>>> renders it=20
>>>>> > ill-formed. Is this intended by design?=20
>>>>>
>>>>> Yes, because attempts to copy the resulting any would need to always=
=20
>>>>> throw.=20
>>>>> That seems undesirable and viral.=20
>>>>>
>>>>
>>>> Agreed. Every `any` instance should have the same behavior, outside of=
=20
>>>> an `any_cast`.
>>>>
>>>> If you need the type-hiding effects of `any`, but allowing for=20
>>>> non-copyable types, then this should be a *different* type. Perhaps=20
>>>> `unique_any`. There could even be some interop between the two types, =
with=20
>>>> `any` being convertible to a `unique_any` (but obviously not vice-vers=
a).
>>>>
>>>
>>> Well, I agree that they should be different types for the purpose of=20
>>> static type checking.
>>>
>>> However, literally it is strange to constraint the contained type of=20
>>> "any" rather than of "any_copyable".
>>>
>>> Perhaps I need one more "unique_any", and then there can be=20
>>> "variant<any, unique_any>"
>>>
>>
>> How will that help? `unique_any` is non-copyable. And if a `variant`=20
>> contains any type that is non-copyable, the variant itself is non-copyab=
le.=20
>> Same goes for `optional`.
>>
>> So you've accomplished nothing more than just using `unique_any` directl=
y.
>>
>> My fault. I should say it is a sum type (in type theory sense) which can=
=20
> behave as either one of its component when appropriate.=20
>
> I was partially wrong here because:
>
> - This is not implementable in pure library way under current core=20
> language rules. I'd use "__variant" rather than "variant" to make it=
=20
> clearer.
> - I didn't read your answer previous carefully enough. Actually, I=20
> came up with the name of "unique_any" by myself several minutes after =
my=20
> original post, and then found it is the same thing you suggested in yo=
ur=20
> answer, but I didn't notice the interop between two types. So more=20
> importantly, since one can convert to other,
>
> You cannot put a non-copyable type in `any`. And `unique_any` would be=20
*non-copyable*. Therefore, while you can convert an `any` into a=20
`unique_any`, you cannot go the other way.
The interop must be uni-directional.
=20
> It's not clear what exactly you want here. You want a type which can stor=
e=20
>> anything. But you don't seem to want it to be a *value* type. Because=20
>> that's what makes `any` require the type to be copyable. The closest you=
're=20
>> going to get to that is `shared_ptr<unique_any>`: a memory-safe referenc=
e=20
>> type to a possibly-non-copyable value that could store any type.
>>
>
>
> It may sound strange to deliberately not differentiate the two types=20
> statically, but it does make sense in several cases. One practical reason=
=20
> is compatibility, perhaps at both API/ABI level. Because type-erased type=
=20
> is a useful way to hide some implementation details, it should be better=
=20
> stable at least in public API (that API expose "any" should be somewhat=
=20
> low-level, though). Ideally, I can delay the choice of disallowing the co=
py=20
> to specific portion of client code while stay binary compatible with=20
> reasonably useful functionality and reusablity. The type=20
> "std::unique_ptr<std::any>" should work here, but it introduces an extra=
=20
> level of indirection and one more hole of null state (as I mentioned, I=
=20
> even don't want default-initialized value of "any") which is not desired.=
=20
> It is also exposed as "reference type" not desired in several cases (e.g.=
=20
> type-erased scope guard storage, though "unique_any" may be enough in thi=
s=20
> specific case because copy of guards make little sense), which may lead t=
o=20
> confusion (though an alias will simply help). So a type with "mixed"=20
> behavior is still useful.
>
If you want all of that, fine. But `any` isn't going to be that type.
--=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/421df198-c9cd-42d0-825f-b27d409b08d9%40isocpp.or=
g.
------=_Part_13290_2054224471.1461160542543
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, April 19, 2016 at 9:44:26 PM UTC-4, FrankHB198=
9 wrote:<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">=E5=
=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC+8=
=E4=B8=8A=E5=8D=884:57:45=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, April 19,=
2016 at 3:05:17 PM UTC-4, FrankHB1989 wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr">=E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=
=98=9F=E6=9C=9F=E4=BA=8C UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bola=
s=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr">On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex">On 19 April 2016 at 14:58, F=
rankHB1989 <<a rel=3D"nofollow">frank...@gmail.com</a>> wrote:
<br>> Currently std::any can't be initialized by a value of noncopya=
ble type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<br></div></div></blockquote><div><br>Well, I a=
gree that they should be different types for the purpose of static type che=
cking.<br><br>However, literally it is strange to constraint the contained =
type of "any" rather than of "any_copyable".<br><br>Per=
haps I need one more "unique_any", and then there can be "va=
riant<any, unique_any>"</div></div></blockquote><div><br>How wil=
l that help? `unique_any` is non-copyable. And if a `variant` contains any =
type that is non-copyable, the variant itself is non-copyable. Same goes fo=
r `optional`.<br><br>So you've accomplished nothing more than just usin=
g `unique_any` directly.<br><br></div></div></blockquote><div>My fault. I s=
hould say it is a sum type (in type theory sense) which can behave as eithe=
r one of its component when appropriate. <br><br>I was partially wrong here=
because:<br><ul><li>This is not implementable in pure library way under cu=
rrent core language rules. I'd use "__variant" rather than &q=
uot;variant" to make it clearer.</li><li>I didn't read your answer=
previous carefully enough. Actually, I came up with the name of "uniq=
ue_any" by myself several minutes after my original post, and then fou=
nd it is the same thing you suggested in your answer, but I didn't noti=
ce the interop between two types. So more importantly, since one can conver=
t to other,</li></ul></div></div></blockquote><div>You cannot put a non-cop=
yable type in `any`. And `unique_any` would be <i>non-copyable</i>. Therefo=
re, while you can convert an `any` into a `unique_any`, you cannot go the o=
ther way.<br><br>The interop must be uni-directional.<br>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>It's not clear what exactl=
y you want here. You want a type which can store anything. But you don'=
t seem to want it to be a <i>value</i> type. Because that's what makes =
`any` require the type to be copyable. The closest you're going to get =
to that is `shared_ptr<unique_any>`: a memory-safe reference type to =
a possibly-non-copyable value that could store any type.</div></div></block=
quote><div><br><br>It may sound strange to deliberately not differentiate t=
he two types statically, but it does make sense in several cases. One pract=
ical reason is compatibility, perhaps at both API/ABI level. Because type-e=
rased type is a useful way to hide some implementation details, it=20
should be better stable at least in public API (that API expose "any&q=
uot; should be somewhat low-level, though). Ideally, I can delay the=20
choice of disallowing the copy to specific portion of client code while sta=
y binary
compatible with reasonably useful functionality and reusablity. The type &=
quot;std::unique_ptr<std::any>" should work=20
here, but it introduces an extra level of indirection and one more hole=20
of null state (as I mentioned, I even don't want default-initialized=20
value of "any") which is not desired. It is also exposed as "=
;reference type" not desired in several cases (e.g. type-erased scope =
guard storage, though "unique_any" may be enough in this specific=
case because copy of guards make little sense), which may lead to confusio=
n (though an alias will simply help). So a type with "mixed" beha=
vior is=20
still useful.<br></div></div></blockquote><div><br>If you want all of that,=
fine. But `any` isn't going to be that type.<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/421df198-c9cd-42d0-825f-b27d409b08d9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/421df198-c9cd-42d0-825f-b27d409b08d9=
%40isocpp.org</a>.<br />
------=_Part_13290_2054224471.1461160542543--
------=_Part_13289_1448601370.1461160542542--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Wed, 20 Apr 2016 07:30:04 -0700 (PDT)
Raw View
------=_Part_14489_1845137417.1461162604972
Content-Type: multipart/alternative;
boundary="----=_Part_14490_1229248350.1461162604973"
------=_Part_14490_1229248350.1461162604973
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC=
+8=E4=B8=8B=E5=8D=889:55:43=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Tuesday, April 19, 2016 at 9:44:26 PM UTC-4, FrankHB1989 wrote:
>>
>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 =
UTC+8=E4=B8=8A=E5=8D=884:57:45=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>>
>>> On Tuesday, April 19, 2016 at 3:05:17 PM UTC-4, FrankHB1989 wrote:
>>>>
>>>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=
=8C UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=
=EF=BC=9A
>>>>>
>>>>> On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen=20
>>>>> wrote:
>>>>>>
>>>>>> On 19 April 2016 at 14:58, FrankHB1989 <frank...@gmail.com> wrote:=
=20
>>>>>> > Currently std::any can't be initialized by a value of noncopyable=
=20
>>>>>> type=20
>>>>>> > through the constructor template because [any.cons]/7 explicitly=
=20
>>>>>> renders it=20
>>>>>> > ill-formed. Is this intended by design?=20
>>>>>>
>>>>>> Yes, because attempts to copy the resulting any would need to always=
=20
>>>>>> throw.=20
>>>>>> That seems undesirable and viral.=20
>>>>>>
>>>>>
>>>>> Agreed. Every `any` instance should have the same behavior, outside o=
f=20
>>>>> an `any_cast`.
>>>>>
>>>>> If you need the type-hiding effects of `any`, but allowing for=20
>>>>> non-copyable types, then this should be a *different* type. Perhaps=
=20
>>>>> `unique_any`. There could even be some interop between the two types,=
with=20
>>>>> `any` being convertible to a `unique_any` (but obviously not vice-ver=
sa).
>>>>>
>>>>
>>>> Well, I agree that they should be different types for the purpose of=
=20
>>>> static type checking.
>>>>
>>>> However, literally it is strange to constraint the contained type of=
=20
>>>> "any" rather than of "any_copyable".
>>>>
>>>> Perhaps I need one more "unique_any", and then there can be=20
>>>> "variant<any, unique_any>"
>>>>
>>>
>>> How will that help? `unique_any` is non-copyable. And if a `variant`=20
>>> contains any type that is non-copyable, the variant itself is non-copya=
ble.=20
>>> Same goes for `optional`.
>>>
>>> So you've accomplished nothing more than just using `unique_any`=20
>>> directly.
>>>
>>> My fault. I should say it is a sum type (in type theory sense) which ca=
n=20
>> behave as either one of its component when appropriate.=20
>>
>> I was partially wrong here because:
>>
>> - This is not implementable in pure library way under current core=20
>> language rules. I'd use "__variant" rather than "variant" to make it=
=20
>> clearer.
>> - I didn't read your answer previous carefully enough. Actually, I=20
>> came up with the name of "unique_any" by myself several minutes after=
my=20
>> original post, and then found it is the same thing you suggested in y=
our=20
>> answer, but I didn't notice the interop between two types. So more=20
>> importantly, since one can convert to other,
>>
>> You cannot put a non-copyable type in `any`. And `unique_any` would be=
=20
> *non-copyable*. Therefore, while you can convert an `any` into a=20
> `unique_any`, you cannot go the other way.
>
> The interop must be uni-directional.
>
Fine.
=20
> =20
>
>> It's not clear what exactly you want here. You want a type which can=20
>>> store anything. But you don't seem to want it to be a *value* type.=20
>>> Because that's what makes `any` require the type to be copyable. The=20
>>> closest you're going to get to that is `shared_ptr<unique_any>`: a=20
>>> memory-safe reference type to a possibly-non-copyable value that could=
=20
>>> store any type.
>>>
>>
>>
>> It may sound strange to deliberately not differentiate the two types=20
>> statically, but it does make sense in several cases. One practical reaso=
n=20
>> is compatibility, perhaps at both API/ABI level. Because type-erased typ=
e=20
>> is a useful way to hide some implementation details, it should be better=
=20
>> stable at least in public API (that API expose "any" should be somewhat=
=20
>> low-level, though). Ideally, I can delay the choice of disallowing the c=
opy=20
>> to specific portion of client code while stay binary compatible with=20
>> reasonably useful functionality and reusablity. The type=20
>> "std::unique_ptr<std::any>" should work here, but it introduces an extra=
=20
>> level of indirection and one more hole of null state (as I mentioned, I=
=20
>> even don't want default-initialized value of "any") which is not desired=
..=20
>> It is also exposed as "reference type" not desired in several cases (e.g=
..=20
>> type-erased scope guard storage, though "unique_any" may be enough in th=
is=20
>> specific case because copy of guards make little sense), which may lead =
to=20
>> confusion (though an alias will simply help). So a type with "mixed"=20
>> behavior is still useful.
>>
>
> If you want all of that, fine. But `any` isn't going to be that type.
>
OK. Then I have to figure out a proper name for that new type... :(
=20
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f849124d-a17c-4f6d-b598-5f5ec387c230%40isocpp.or=
g.
------=_Part_14490_1229248350.1461162604973
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8B=E5=8D=889:55:43=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Tuesday, April 19, 2016 at 9:44:26 PM UTC-4, FrankHB1989 wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=E5=9C=A8 2016=
=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=
=8D=884:57:45=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, April 19, 2016 at 3:0=
5:17 PM UTC-4, FrankHB1989 wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr">=E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=
=9F=E4=BA=8C UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=
=E9=81=93=EF=BC=9A<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"ltr">=
On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">On 19 April 2016 at 14:58, FrankHB1989=
<<a rel=3D"nofollow">frank...@gmail.com</a>> wrote:
<br>> Currently std::any can't be initialized by a value of noncopya=
ble type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<br></div></div></blockquote><div><br>Well, I a=
gree that they should be different types for the purpose of static type che=
cking.<br><br>However, literally it is strange to constraint the contained =
type of "any" rather than of "any_copyable".<br><br>Per=
haps I need one more "unique_any", and then there can be "va=
riant<any, unique_any>"</div></div></blockquote><div><br>How wil=
l that help? `unique_any` is non-copyable. And if a `variant` contains any =
type that is non-copyable, the variant itself is non-copyable. Same goes fo=
r `optional`.<br><br>So you've accomplished nothing more than just usin=
g `unique_any` directly.<br><br></div></div></blockquote><div>My fault. I s=
hould say it is a sum type (in type theory sense) which can behave as eithe=
r one of its component when appropriate. <br><br>I was partially wrong here=
because:<br><ul><li>This is not implementable in pure library way under cu=
rrent core language rules. I'd use "__variant" rather than &q=
uot;variant" to make it clearer.</li><li>I didn't read your answer=
previous carefully enough. Actually, I came up with the name of "uniq=
ue_any" by myself several minutes after my original post, and then fou=
nd it is the same thing you suggested in your answer, but I didn't noti=
ce the interop between two types. So more importantly, since one can conver=
t to other,</li></ul></div></div></blockquote><div>You cannot put a non-cop=
yable type in `any`. And `unique_any` would be <i>non-copyable</i>. Therefo=
re, while you can convert an `any` into a `unique_any`, you cannot go the o=
ther way.<br><br>The interop must be uni-directional.<br></div></div></bloc=
kquote><div>Fine.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div dir=3D"ltr"><div>=C2=A0</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"><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"><div>It's not clear what exactly you want here. You want a type wh=
ich can store anything. But you don't seem to want it to be a <i>value<=
/i> type. Because that's what makes `any` require the type to be copyab=
le. The closest you're going to get to that is `shared_ptr<unique_an=
y>`: a memory-safe reference type to a possibly-non-copyable value that =
could store any type.</div></div></blockquote><div><br><br>It may sound str=
ange to deliberately not differentiate the two types statically, but it doe=
s make sense in several cases. One practical reason is compatibility, perha=
ps at both API/ABI level. Because type-erased type is a useful way to hide =
some implementation details, it=20
should be better stable at least in public API (that API expose "any&q=
uot; should be somewhat low-level, though). Ideally, I can delay the=20
choice of disallowing the copy to specific portion of client code while sta=
y binary
compatible with reasonably useful functionality and reusablity. The type &=
quot;std::unique_ptr<std::any>" should work=20
here, but it introduces an extra level of indirection and one more hole=20
of null state (as I mentioned, I even don't want default-initialized=20
value of "any") which is not desired. It is also exposed as "=
;reference type" not desired in several cases (e.g. type-erased scope =
guard storage, though "unique_any" may be enough in this specific=
case because copy of guards make little sense), which may lead to confusio=
n (though an alias will simply help). So a type with "mixed" beha=
vior is=20
still useful.<br></div></div></blockquote><div><br>If you want all of that,=
fine. But `any` isn't going to be that type.<br></div></div></blockquo=
te><div>OK. Then I have to figure out a proper name for that new type... :(=
<br>=C2=A0<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/f849124d-a17c-4f6d-b598-5f5ec387c230%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f849124d-a17c-4f6d-b598-5f5ec387c230=
%40isocpp.org</a>.<br />
------=_Part_14490_1229248350.1461162604973--
------=_Part_14489_1845137417.1461162604972--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Wed, 20 Apr 2016 10:42:26 -0400
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
255, 255); line-height: initial;"> =
<div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">> <span style=3D"line-height: initial;">Note the concep=
t of "value type" or "reference type" is not of C++ language rules, so expe=
ctation on "copyable" is not always fair.</span></div><div style=3D"width: =
100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sa=
ns-serif; color: rgb(31, 73, 125); text-align: initial; background-color: r=
gb(255, 255, 255);"><span style=3D"line-height: initial;"><br></span></div>=
<div style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate=
Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial=
; background-color: rgb(255, 255, 255);"><span style=3D"line-height: initia=
l;"><br></span></div><div style=3D"width: 100%; font-size: initial; font-fa=
mily: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125)=
; text-align: initial; background-color: rgb(255, 255, 255);"><span style=
=3D"line-height: initial;">"Value type" or Regular may not be explicitly st=
ated, but it permeates the language, and particularly the library.(you get =
copy constructors for free, and =3D=3D probably in C++17, pass by value is =
the default, pointers - which enable reference semantics - are Regular, etc=
; all containers are Regular and we're built to hold Regular types (and the=
n stretched in places to support non-Regular when possible, etc; etc, etc)<=
/span></div><div style=3D"width: 100%; font-size: initial; font-family: Cal=
ibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-al=
ign: initial; background-color: rgb(255, 255, 255);"><span style=3D"line-he=
ight: initial;"><br></span></div><div style=3D"width: 100%; font-size: init=
ial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(=
31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);"><=
span style=3D"line-height: initial;">C++ is a Value-Oriented Language. =
;</span></div><div style=3D"width: 100%; font-size: initial; font-family: C=
alibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-=
align: initial; background-color: rgb(255, 255, 255);"><span style=3D"line-=
height: initial;"><br></span></div><div style=3D"width: 100%; font-size: in=
itial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rg=
b(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);"=
><span style=3D"line-height: initial;"> </span></div><div style=3D"wid=
th: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif=
, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-colo=
r: rgb(255, 255, 255);"><br></div><div style=3D"width: 100%; font-size: ini=
tial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb=
(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">=
<br></div> =
<div st=
yle=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', =
sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; backg=
round-color: rgb(255, 255, 255);"><br style=3D"display:initial"></div> =
=
=
<div style=3D"font-size: initial; f=
ont-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73=
, 125); text-align: initial; background-color: rgb(255, 255, 255);">Sent&nb=
sp;from my BlackBerry portable Babbage Device</div=
> =
=
<table width=3D"100%" style=3D"background-colo=
r:white;border-spacing:0px;"> <tbody><tr><td colspan=3D"2" style=3D"font-si=
ze: initial; text-align: initial; background-color: rgb(255, 255, 255);"> =
<div style=3D"border-style: solid none none; borde=
r-top-color: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0in 0i=
n; font-family: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;"> <=
div><b>From: </b>FrankHB1989</div><div><b>Sent: </b>Tuesday, April 19, 2016=
9:44 PM</div><div><b>To: </b>ISO C++ Standard - Future Proposals</div><div=
><b>Reply To: </b>std-proposals@isocpp.org</div><div><b>Subject: </b>Re: [s=
td-proposals] any vs. CopyConstructible</div></div></td></tr></tbody></tabl=
e><div style=3D"border-style: solid none none; border-top-color: rgb(186, 1=
88, 209); border-top-width: 1pt; font-size: initial; text-align: initial; b=
ackground-color: rgb(255, 255, 255);"></div><br><div id=3D"_originalContent=
" style=3D""><div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=
=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=8D=884:57:45=EF=BC=
=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><br><br>On Tuesday, April 19, 2016 at 3:05:17 P=
M UTC-4, FrankHB1989 wrote:<blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=
=9C=9F=E4=BA=8C UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=
=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><br><br>On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilaine=
n wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">On 19 April 2016 at 14:58, =
FrankHB1989 <<a rel=3D"nofollow">frank...@gmail.com</a>> wrote:
<br>> Currently std::any can't be initialized by a value of noncopyable =
type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<br></div></div></blockquote><div><br>Well, I a=
gree that they should be different types for the purpose of static type che=
cking.<br><br>However, literally it is strange to constraint the contained =
type of "any" rather than of "any_copyable".<br><br>Perhaps I need one more=
"unique_any", and then there can be "variant<any, unique_any>"</div>=
</div></blockquote><div><br>How will that help? `unique_any` is non-copyabl=
e. And if a `variant` contains any type that is non-copyable, the variant i=
tself is non-copyable. Same goes for `optional`.<br><br>So you've accomplis=
hed nothing more than just using `unique_any` directly.<br><br></div></div>=
</blockquote><div>My fault. I should say it is a sum type (in type theory s=
ense) which can behave as either one of its component when appropriate. <br=
><br>I was partially wrong here because:<br><ul><li>This is not implementab=
le in pure library way under current core language rules. I'd use "__varian=
t" rather than "variant" to make it clearer.</li><li>I didn't read your ans=
wer previous carefully enough. Actually, I came up with the name of "unique=
_any" by myself several minutes after my original post, and then found it i=
s the same thing you suggested in your answer, but I didn't notice the inte=
rop between two types. So more importantly, since one can convert to other,=
it is not necessary to implement it by a (core language based) sum type he=
re (even the latter should benefit in general, e.g. to replace builtin poin=
ters).<br></li></ul> <br></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"><div>It's not clear what exactly you want here. You =
want a type which can store anything. But you don't seem to want it to be a=
<i>value</i> type. Because that's what makes `any` require the type to be =
copyable. The closest you're going to get to that is `shared_ptr<unique_=
any>`: a memory-safe reference type to a possibly-non-copyable value tha=
t could store any type.</div></div></blockquote><div><br><br>It may sound s=
trange to deliberately not differentiate the two types statically, but it d=
oes make sense in several cases. One practical reason is compatibility, per=
haps at both API/ABI level. Because type-erased type is a useful way to hid=
e some implementation details, it=20
should be better stable at least in public API (that API expose "any" shoul=
d be somewhat low-level, though). Ideally, I can delay the=20
choice of disallowing the copy to specific portion of client code while sta=
y binary
compatible with reasonably useful functionality and reusablity. The type "=
std::unique_ptr<std::any>" should work=20
here, but it introduces an extra level of indirection and one more hole=20
of null state (as I mentioned, I even don't want default-initialized=20
value of "any") which is not desired. It is also exposed as "reference type=
" not desired in several cases (e.g. type-erased scope guard storage, thoug=
h "unique_any" may be enough in this specific case because copy of guards m=
ake little sense), which may lead to confusion (though an alias will simply=
help). So a type with "mixed" behavior is=20
still useful.<br><br>Note the concept of "value type" or "reference type" i=
s not of C++ language rules, so expectation on "copyable" is not always fai=
r. They are built in some other languages because they are typically useful=
, but as said above, an object whose static type is not exact one of "value=
" or "reference" still plays some roles better (this can be impossible in l=
anguages which differentiate "value" and "reference" explicitly in their co=
re rules). And even in most cases the distinction of "value" or "reference"=
should be better kept, it is specifically not so good for the meaning of "=
any". The "mixed" behavior with name "any" here is more friendly to the pri=
nciple to=20
least astonishment.<br> <br></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups "=
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/16c9147e-c5d1-4e89-b77d-3e2f0397c136%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/16c9147e-c5d1-4e89-b77d-3e2f0397=
c136%40isocpp.org</a>.<br>
<br><!--end of _originalContent --></div></body></html>
<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/20160420144226.4911184.23927.10026%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com=
/a/isocpp.org/d/msgid/std-proposals/20160420144226.4911184.23927.10026%40gm=
ail.com</a>.<br />
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Wed, 20 Apr 2016 20:05:23 -0700 (PDT)
Raw View
------=_Part_591_273749836.1461207923968
Content-Type: multipart/alternative;
boundary="----=_Part_592_1530459537.1461207923969"
------=_Part_592_1530459537.1461207923969
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC=
+8=E4=B8=8B=E5=8D=8810:42:30=EF=BC=8CTony V E=E5=86=99=E9=81=93=EF=BC=9A
>
> > Note the concept of "value type" or "reference type" is not of C++=20
> language rules, so expectation on "copyable" is not always fair.
>
>
> "Value type" or Regular may not be explicitly stated, but it permeates th=
e=20
> language, and particularly the library.(you get copy constructors for fre=
e,=20
> and =3D=3D probably in C++17, pass by value is the default, pointers - wh=
ich=20
> enable reference semantics - are Regular, etc; all containers are Regular=
=20
> and we're built to hold Regular types (and then stretched in places to=20
> support non-Regular when possible, etc; etc, etc)
>
> C++ is a Value-Oriented Language.=20
>
> =20
>
Pass-by-value is inherited from C, extended as copy initialization in C++.=
=20
But this does not necessarily call the copy constructor. An object of class=
=20
type with deleted copy constructor may still be copy-initialized by moving.=
=20
Only initialization of references has the genuine reference semantics. The=
=20
result is we have a few exceptions of pass-by-reference types and all other=
=20
types are passed-by-value - either copyable or not copyable.
Strictly speaking, the "reference type" mentioned above is just whose=20
values are not expected to be copied in general (perhaps too expensive), it=
=20
can still have a well-formed copy-constructor, e.g. a container. To force=
=20
it noncopyable is not a good idea because the copy can still be useful in a=
=20
few cases, and there is no general way to emulate "value semantics" by=20
noncopyable types. This is the reason to have defaulted copy constructor=20
mechanism and to avoid this concept in the core language.
So basically I agree with the view of "value-oriented language" in this=20
sense.
But type erasure is not about passing the values. These properties are=20
*orthogonal*. Even if "any" is not copyable (and even not movable), it can=
=20
still be naturally used in specific ways.
>
>
> Sent from my BlackBerry portable Babbage Device
> *From: *FrankHB1989
> *Sent: *Tuesday, April 19, 2016 9:44 PM
> *To: *ISO C++ Standard - Future Proposals
> *Reply To: *std-pr...@isocpp.org <javascript:>
> *Subject: *Re: [std-proposals] any vs. CopyConstructible
>
>
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 U=
TC+8=E4=B8=8A=E5=8D=884:57:45=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>>
>>
>> On Tuesday, April 19, 2016 at 3:05:17 PM UTC-4, FrankHB1989 wrote:
>>>
>>>
>>>
>>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=8C=
UTC+8=E4=B8=8B=E5=8D=8811:50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=
=BC=9A
>>>>
>>>>
>>>>
>>>> On Tuesday, April 19, 2016 at 8:08:51 AM UTC-4, Ville Voutilainen wrot=
e:
>>>>>
>>>>> On 19 April 2016 at 14:58, FrankHB1989 <frank...@gmail.com> wrote:=20
>>>>> > Currently std::any can't be initialized by a value of noncopyable=
=20
>>>>> type=20
>>>>> > through the constructor template because [any.cons]/7 explicitly=20
>>>>> renders it=20
>>>>> > ill-formed. Is this intended by design?=20
>>>>>
>>>>> Yes, because attempts to copy the resulting any would need to always=
=20
>>>>> throw.=20
>>>>> That seems undesirable and viral.=20
>>>>>
>>>>
>>>> Agreed. Every `any` instance should have the same behavior, outside of=
=20
>>>> an `any_cast`.
>>>>
>>>> If you need the type-hiding effects of `any`, but allowing for=20
>>>> non-copyable types, then this should be a *different* type. Perhaps=20
>>>> `unique_any`. There could even be some interop between the two types, =
with=20
>>>> `any` being convertible to a `unique_any` (but obviously not vice-vers=
a).
>>>>
>>>
>>> Well, I agree that they should be different types for the purpose of=20
>>> static type checking.
>>>
>>> However, literally it is strange to constraint the contained type of=20
>>> "any" rather than of "any_copyable".
>>>
>>> Perhaps I need one more "unique_any", and then there can be=20
>>> "variant<any, unique_any>"
>>>
>>
>> How will that help? `unique_any` is non-copyable. And if a `variant`=20
>> contains any type that is non-copyable, the variant itself is non-copyab=
le.=20
>> Same goes for `optional`.
>>
>> So you've accomplished nothing more than just using `unique_any` directl=
y.
>>
>> My fault. I should say it is a sum type (in type theory sense) which can=
=20
> behave as either one of its component when appropriate.=20
>
> I was partially wrong here because:
>
> - This is not implementable in pure library way under current core=20
> language rules. I'd use "__variant" rather than "variant" to make it=
=20
> clearer.
> - I didn't read your answer previous carefully enough. Actually, I=20
> came up with the name of "unique_any" by myself several minutes after =
my=20
> original post, and then found it is the same thing you suggested in yo=
ur=20
> answer, but I didn't notice the interop between two types. So more=20
> importantly, since one can convert to other, it is not necessary to=20
> implement it by a (core language based) sum type here (even the latter=
=20
> should benefit in general, e.g. to replace builtin pointers).
> =20
> =20
>
>> It's not clear what exactly you want here. You want a type which can=20
>> store anything. But you don't seem to want it to be a *value* type.=20
>> Because that's what makes `any` require the type to be copyable. The=20
>> closest you're going to get to that is `shared_ptr<unique_any>`: a=20
>> memory-safe reference type to a possibly-non-copyable value that could=
=20
>> store any type.
>>
>
>
> It may sound strange to deliberately not differentiate the two types=20
> statically, but it does make sense in several cases. One practical reason=
=20
> is compatibility, perhaps at both API/ABI level. Because type-erased type=
=20
> is a useful way to hide some implementation details, it should be better=
=20
> stable at least in public API (that API expose "any" should be somewhat=
=20
> low-level, though). Ideally, I can delay the choice of disallowing the co=
py=20
> to specific portion of client code while stay binary compatible with=20
> reasonably useful functionality and reusablity. The type=20
> "std::unique_ptr<std::any>" should work here, but it introduces an extra=
=20
> level of indirection and one more hole of null state (as I mentioned, I=
=20
> even don't want default-initialized value of "any") which is not desired.=
=20
> It is also exposed as "reference type" not desired in several cases (e.g.=
=20
> type-erased scope guard storage, though "unique_any" may be enough in thi=
s=20
> specific case because copy of guards make little sense), which may lead t=
o=20
> confusion (though an alias will simply help). So a type with "mixed"=20
> behavior is still useful.
>
> Note the concept of "value type" or "reference type" is not of C++=20
> language rules, so expectation on "copyable" is not always fair. They are=
=20
> built in some other languages because they are typically useful, but as=
=20
> said above, an object whose static type is not exact one of "value" or=20
> "reference" still plays some roles better (this can be impossible in=20
> languages which differentiate "value" and "reference" explicitly in their=
=20
> core rules). And even in most cases the distinction of "value" or=20
> "reference" should be better kept, it is specifically not so good for the=
=20
> meaning of "any". The "mixed" behavior with name "any" here is more=20
> friendly to the principle to least astonishment.
> =20
>
> --=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> To view this discussion on the web visit=20
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/16c9147e-c5d=
1-4e89-b77d-3e2f0397c136%40isocpp.org=20
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/16c9147e-c5=
d1-4e89-b77d-3e2f0397c136%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
>
--=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/113cd504-5658-4558-995c-1c0c0d17a70a%40isocpp.or=
g.
------=_Part_592_1530459537.1461207923969
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8B=E5=8D=8810:42:30=EF=BC=8CTony V E=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div s=
tyle=3D"background-color:rgb(255,255,255);line-height:initial" lang=3D"en-U=
S"> =
<div style=3D"width:100%;font-size:initial;font-family:Calibr=
i,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-align=
:initial;background-color:rgb(255,255,255)">>=C2=A0<span style=3D"line-h=
eight:initial">Note the concept of "value type" or "referenc=
e type" is not of C++ language rules, so expectation on "copyable=
" is not always fair.</span></div><div style=3D"width:100%;font-size:i=
nitial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:=
rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)"><span =
style=3D"line-height:initial"><br></span></div><div style=3D"width:100%;fon=
t-size:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-seri=
f;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)=
"><span style=3D"line-height:initial"><br></span></div><div style=3D"width:=
100%;font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,s=
ans-serif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,=
255,255)"><span style=3D"line-height:initial">"Value type" or Reg=
ular may not be explicitly stated, but it permeates the language, and parti=
cularly the library.(you get copy constructors for free, and =3D=3D probabl=
y in C++17, pass by value is the default, pointers - which enable reference=
semantics - are Regular, etc; all containers are Regular and we're bui=
lt to hold Regular types (and then stretched in places to support non-Regul=
ar when possible, etc; etc, etc)</span></div><div style=3D"width:100%;font-=
size:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;=
color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,255)">=
<span style=3D"line-height:initial"><br></span></div><div style=3D"width:10=
0%;font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,san=
s-serif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,25=
5,255)"><span style=3D"line-height:initial">C++ is a Value-Oriented Languag=
e.=C2=A0</span></div><div style=3D"width:100%;font-size:initial;font-family=
:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);tex=
t-align:initial;background-color:rgb(255,255,255)"><span style=3D"line-heig=
ht:initial"><br></span></div><div style=3D"width:100%;font-size:initial;fon=
t-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,=
125);text-align:initial;background-color:rgb(255,255,255)"><span style=3D"l=
ine-height:initial">=C2=A0</span></div></div></blockquote><div>Pass-by-valu=
e is inherited from C, extended as copy initialization in C++. But this doe=
s not necessarily call the copy constructor. An object of class type with d=
eleted copy constructor may still be copy-initialized by moving. Only initi=
alization of references has the genuine reference semantics. The result is =
we have a few exceptions of pass-by-reference types and all other types are=
passed-by-value - either copyable or not copyable.<br><br>Strictly speakin=
g, the "reference type" mentioned above is just whose values are =
not expected to be copied in general (perhaps too expensive), it can still =
have a well-formed copy-constructor, e.g. a container. To force it noncopya=
ble is not a good idea because the copy can still be useful in a few cases,=
and there is no general way to emulate "value semantics" by nonc=
opyable types. This is the reason to have defaulted copy constructor mechan=
ism and to avoid this concept in the core language.<br><br>So basically I a=
gree with the view of "value-oriented language" in this sense.<br=
><br>But type erasure is not about passing the values. These properties are=
<i>orthogonal</i>. Even if "any" is not copyable (and even not m=
ovable), it can still be naturally used in specific ways.<br><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"background-color:rgb=
(255,255,255);line-height:initial" lang=3D"en-US"><div style=3D"width:100%;=
font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,sans-s=
erif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,255,2=
55)"><br></div><div style=3D"width:100%;font-size:initial;font-family:Calib=
ri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-alig=
n:initial;background-color:rgb(255,255,255)"><br></div> =
=
<div style=3D"width:100%;font-size:in=
itial;font-family:Calibri,'Slate Pro',sans-serif,sans-serif;color:r=
gb(31,73,125);text-align:initial;background-color:rgb(255,255,255)"><br sty=
le=3D"display:initial"></div> =
=
<=
div style=3D"font-size:initial;font-family:Calibri,'Slate Pro',sans=
-serif,sans-serif;color:rgb(31,73,125);text-align:initial;background-color:=
rgb(255,255,255)">Sent=C2=A0from=C2=A0my=C2=A0BlackBerry=C2=A0<wbr>portable=
=C2=A0Babbage=C2=A0Device</div> =
=
<table style=3D"=
background-color:white;border-spacing:0px" width=3D"100%"> <tbody><tr><td c=
olspan=3D"2" style=3D"font-size:initial;text-align:initial;background-color=
:rgb(255,255,255)"> <div style=3D"border-style:so=
lid none none;border-top-color:rgb(181,196,223);border-top-width:1pt;paddin=
g:3pt 0in 0in;font-family:Tahoma,'BB Alpha Sans','Slate Pro'=
;;font-size:10pt"> <div><b>From: </b>FrankHB1989</div><div><b>Sent: </b>Tu=
esday, April 19, 2016 9:44 PM</div><div><b>To: </b>ISO C++ Standard - Futur=
e Proposals</div><div><b>Reply To: </b><a href=3D"javascript:" target=3D"_b=
lank" gdf-obfuscated-mailto=3D"vcklsjFGBgAJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D=
'javascript:';return true;">std-pr...@isocpp.org</a></div><div><b>S=
ubject: </b>Re: [std-proposals] any vs. CopyConstructible</div></div></td><=
/tr></tbody></table><div style=3D"border-style:solid none none;border-top-c=
olor:rgb(186,188,209);border-top-width:1pt;font-size:initial;text-align:ini=
tial;background-color:rgb(255,255,255)"></div><br><div><div dir=3D"ltr"><br=
><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8820=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=
=89 UTC+8=E4=B8=8A=E5=8D=884:57:45=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=
=BC=9A<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"><br><br>On T=
uesday, April 19, 2016 at 3:05:17 PM UTC-4, FrankHB1989 wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B4=
4=E6=9C=8819=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=8C UTC+8=E4=B8=8B=E5=8D=8811:=
50:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><br><br>On Tuesday, April 19, 2016 at 8:0=
8:51 AM UTC-4, Ville Voutilainen wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex">On 19 April 2016 at 14:58, FrankHB1989 <<a rel=3D"nofollow">frank...=
@gmail.com</a>> wrote:
<br>> Currently std::any can't be initialized by a value of noncopya=
ble type
<br>> through the constructor template because [any.cons]/7 explicitly r=
enders it
<br>> ill-formed. Is this intended by design?
<br>
<br>Yes, because attempts to copy the resulting any would need to always th=
row.
<br>That seems undesirable and viral.
<br></blockquote><div><br>Agreed. Every `any` instance should have the same=
behavior, outside of an `any_cast`.<br><br>If you need the type-hiding eff=
ects of `any`, but allowing for non-copyable types, then this should be a <=
i>different</i> type. Perhaps `unique_any`. There could even be some intero=
p between the two types, with `any` being convertible to a `unique_any` (bu=
t obviously not vice-versa).<br></div></div></blockquote><div><br>Well, I a=
gree that they should be different types for the purpose of static type che=
cking.<br><br>However, literally it is strange to constraint the contained =
type of "any" rather than of "any_copyable".<br><br>Per=
haps I need one more "unique_any", and then there can be "va=
riant<any, unique_any>"</div></div></blockquote><div><br>How wil=
l that help? `unique_any` is non-copyable. And if a `variant` contains any =
type that is non-copyable, the variant itself is non-copyable. Same goes fo=
r `optional`.<br><br>So you've accomplished nothing more than just usin=
g `unique_any` directly.<br><br></div></div></blockquote><div>My fault. I s=
hould say it is a sum type (in type theory sense) which can behave as eithe=
r one of its component when appropriate. <br><br>I was partially wrong here=
because:<br><ul><li>This is not implementable in pure library way under cu=
rrent core language rules. I'd use "__variant" rather than &q=
uot;variant" to make it clearer.</li><li>I didn't read your answer=
previous carefully enough. Actually, I came up with the name of "uniq=
ue_any" by myself several minutes after my original post, and then fou=
nd it is the same thing you suggested in your answer, but I didn't noti=
ce the interop between two types. So more importantly, since one can conver=
t to other, it is not necessary to implement it by a (core language based) =
sum type here (even the latter should benefit in general, e.g. to replace b=
uiltin pointers).<br></li></ul>=C2=A0<br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div>It's not clear what exactly you want =
here. You want a type which can store anything. But you don't seem to w=
ant it to be a <i>value</i> type. Because that's what makes `any` requi=
re the type to be copyable. The closest you're going to get to that is =
`shared_ptr<unique_any>`: a memory-safe reference type to a possibly-=
non-copyable value that could store any type.</div></div></blockquote><div>=
<br><br>It may sound strange to deliberately not differentiate the two type=
s statically, but it does make sense in several cases. One practical reason=
is compatibility, perhaps at both API/ABI level. Because type-erased type =
is a useful way to hide some implementation details, it=20
should be better stable at least in public API (that API expose "any&q=
uot; should be somewhat low-level, though). Ideally, I can delay the=20
choice of disallowing the copy to specific portion of client code while sta=
y binary
compatible with reasonably useful functionality and reusablity. The type &=
quot;std::unique_ptr<std::any>" should work=20
here, but it introduces an extra level of indirection and one more hole=20
of null state (as I mentioned, I even don't want default-initialized=20
value of "any") which is not desired. It is also exposed as "=
;reference type" not desired in several cases (e.g. type-erased scope =
guard storage, though "unique_any" may be enough in this specific=
case because copy of guards make little sense), which may lead to confusio=
n (though an alias will simply help). So a type with "mixed" beha=
vior is=20
still useful.<br><br>Note the concept of "value type" or "re=
ference type" is not of C++ language rules, so expectation on "co=
pyable" is not always fair. They are built in some other languages bec=
ause they are typically useful, but as said above, an object whose static t=
ype is not exact one of "value" or "reference" still pl=
ays some roles better (this can be impossible in languages which differenti=
ate "value" and "reference" explicitly in their core ru=
les). And even in most cases the distinction of "value" or "=
reference" should be better kept, it is specifically not so good for t=
he meaning of "any". The "mixed" behavior with name &qu=
ot;any" here is more friendly to the principle to=20
least astonishment.<br>=C2=A0<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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
vcklsjFGBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"vcklsjFGBgAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@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/16c9147e-c5d1-4e89-b77d-3e2f0397c136%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/16c9147e-c5d1-4e89-b77d-3e2f0397c136%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/16c9147e-c5d1-4e89-b77d-3e2f0397c136%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter';return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/16c9147e-c5d1-4e89-<wbr>b77d-=
3e2f0397c136%40isocpp.org</a><wbr>.<br>
<br></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/113cd504-5658-4558-995c-1c0c0d17a70a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/113cd504-5658-4558-995c-1c0c0d17a70a=
%40isocpp.org</a>.<br />
------=_Part_592_1530459537.1461207923969--
------=_Part_591_273749836.1461207923968--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 21 Apr 2016 09:29:28 -0700 (PDT)
Raw View
------=_Part_1168_32886124.1461256168356
Content-Type: multipart/alternative;
boundary="----=_Part_1169_343655073.1461256168357"
------=_Part_1169_343655073.1461256168357
Content-Type: text/plain; charset=UTF-8
On Wednesday, April 20, 2016 at 11:05:24 PM UTC-4, FrankHB1989 wrote:
>
> But type erasure is not about passing the values. These properties are
> *orthogonal*. Even if "any" is not copyable (and even not movable), it
> can still be naturally used in specific ways.
>
I'm not sure what your point is.
Nobody is claiming that different kinds of `any` types with different
properties will be useless. Nobody is claiming that type-erasure requires a
value type.
The point is that, because C++ is a value-oriented language, the standard
library types are predominantly value types. So `any` being a value type is
the right answer for C++ as a value-oriented language.
If you believe that the standard should have a `shared_any`, then propose
that. But `any` isn't going to change just because you want different
behavior.
--
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/62b4a3ee-7c98-41a3-b44b-4f2ca22ff78c%40isocpp.org.
------=_Part_1169_343655073.1461256168357
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, April 20, 2016 at 11:05:24 PM UTC-4, FrankHB=
1989 wrote:<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">Bu=
t type erasure is not about passing the values. These properties are <i>ort=
hogonal</i>. Even if "any" is not copyable (and even not movable)=
, it can still be naturally used in specific ways.<br></div></blockquote><d=
iv><br>I'm not sure what your point is.<br><br>Nobody is claiming that =
different kinds of `any` types with different properties will be useless. N=
obody is claiming that type-erasure requires a value type.<br><br>The point=
is that, because C++ is a value-oriented language, the standard library ty=
pes are predominantly value types. So `any` being a value type is the right=
answer for C++ as a value-oriented language.<br><br>If you believe that th=
e standard should have a `shared_any`, then propose that. But `any` isn'=
;t going to change just because you want different behavior.<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/62b4a3ee-7c98-41a3-b44b-4f2ca22ff78c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/62b4a3ee-7c98-41a3-b44b-4f2ca22ff78c=
%40isocpp.org</a>.<br />
------=_Part_1169_343655073.1461256168357--
------=_Part_1168_32886124.1461256168356--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Thu, 21 Apr 2016 18:29:45 -0700 (PDT)
Raw View
------=_Part_1914_1387942898.1461288585729
Content-Type: multipart/alternative;
boundary="----=_Part_1915_98886545.1461288585729"
------=_Part_1915_98886545.1461288585729
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 UTC=
+8=E4=B8=8A=E5=8D=8812:29:28=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Wednesday, April 20, 2016 at 11:05:24 PM UTC-4, FrankHB1989 wrote:
>>
>> But type erasure is not about passing the values. These properties are=
=20
>> *orthogonal*. Even if "any" is not copyable (and even not movable), it=
=20
>> can still be naturally used in specific ways.
>>
>
> I'm not sure what your point is.
>
> Nobody is claiming that different kinds of `any` types with different=20
> properties will be useless. Nobody is claiming that type-erasure requires=
a=20
> value type.
>
> The point is that, because C++ is a value-oriented language, the standard=
=20
> library types are predominantly value types. So `any` being a value type =
is=20
> the right answer for C++ as a value-oriented language.
>
> I know it clearly, as [any.class]/3 suggested even more specific to `any`=
..
=20
However, to make `any` a "value type" is different to force the type of=20
contained object a "value type". If this is determined by design, what is=
=20
the reason? Just because "the standard library types are predominantly=20
value types"? Well, I don't think `any` is designed for only holding "the=
=20
standard library types".
=20
> If you believe that the standard should have a `shared_any`, then propose=
=20
> that. But `any` isn't going to change just because you want different=20
> behavior.
>
No, I won't. It can't be `shared_any`, because of the semantics. An `any`=
=20
object being copied is not shared with copied instance. The reason of=20
insisting non-sharing as the default behavior of copy constructor in=20
general is exactly what you have said, and I have no problems with it.
BTW, there is one more related subtle problem about `shared_ptr`:=20
`static_pointer_cast` accepts `const shared_ptr<T>&` but not=20
`shared_ptr<T>` or `shared_ptr<T>&&`, even `shared_ptr<T>` can be in the=20
set of "predominantly value types".
=20
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/093aebfa-098e-40c2-a2e8-603ed0a9fa91%40isocpp.or=
g.
------=_Part_1915_98886545.1461288585729
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=BA=94 UTC+8=E4=B8=8A=E5=8D=8812:29:28=EF=BC=8CNicol Bolas=
=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Wednesday, April 20, 2016 at 11:05:24 PM UTC-4, FrankHB198=
9 wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">But type e=
rasure is not about passing the values. These properties are <i>orthogonal<=
/i>. Even if "any" is not copyable (and even not movable), it can=
still be naturally used in specific ways.<br></div></blockquote><div><br>I=
'm not sure what your point is.<br><br>Nobody is claiming that differen=
t kinds of `any` types with different properties will be useless. Nobody is=
claiming that type-erasure requires a value type.<br><br>The point is that=
, because C++ is a value-oriented language, the standard library types are =
predominantly value types. So `any` being a value type is the right answer =
for C++ as a value-oriented language.<br><br></div></div></blockquote><div>=
I know it clearly, as [any.class]/3 suggested even more specific to `any`.<=
br>=C2=A0<br></div><div>However, to make `any` a "value type" is =
different to force the type of contained object a "value type". I=
f this is determined by design, what is the reason? Just because "the =
standard library types are predominantly value types"? Well, I don'=
;t think `any` is designed for only holding "the standard library type=
s".<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div>If you believe that the standard should have a `shared_=
any`, then propose that. But `any` isn't going to change just because y=
ou want different behavior.<br></div></div></blockquote><div><br>No, I won&=
#39;t. It can't be `shared_any`, because of the semantics. An `any` obj=
ect being copied is not shared with copied instance. The reason of insistin=
g non-sharing as the default behavior of copy constructor in general is exa=
ctly what you have said, and I have no problems with it.<br><br>BTW, there =
is one more related subtle problem about `shared_ptr`: `static_pointer_cast=
` accepts `const shared_ptr<T>&` but not `shared_ptr<T>` or=
`shared_ptr<T>&&`, even `shared_ptr<T>` can be in the =
set of "predominantly value types".<br>=C2=A0</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/093aebfa-098e-40c2-a2e8-603ed0a9fa91%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/093aebfa-098e-40c2-a2e8-603ed0a9fa91=
%40isocpp.org</a>.<br />
------=_Part_1915_98886545.1461288585729--
------=_Part_1914_1387942898.1461288585729--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 22 Apr 2016 07:52:00 -0700 (PDT)
Raw View
------=_Part_567_197410772.1461336720404
Content-Type: multipart/alternative;
boundary="----=_Part_568_1156305918.1461336720405"
------=_Part_568_1156305918.1461336720405
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, April 21, 2016 at 9:29:45 PM UTC-4, FrankHB1989 wrote:
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 U=
TC+8=E4=B8=8A=E5=8D=8812:29:28=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>> On Wednesday, April 20, 2016 at 11:05:24 PM UTC-4, FrankHB1989 wrote:
>>>
>>> But type erasure is not about passing the values. These properties are=
=20
>>> *orthogonal*. Even if "any" is not copyable (and even not movable), it=
=20
>>> can still be naturally used in specific ways.
>>>
>>
>> I'm not sure what your point is.
>>
>> Nobody is claiming that different kinds of `any` types with different=20
>> properties will be useless. Nobody is claiming that type-erasure require=
s a=20
>> value type.
>>
>> The point is that, because C++ is a value-oriented language, the standar=
d=20
>> library types are predominantly value types. So `any` being a value type=
is=20
>> the right answer for C++ as a value-oriented language.
>>
>> I know it clearly, as [any.class]/3 suggested even more specific to `any=
`.
> =20
> However, to make `any` a "value type" is different to force the type of=
=20
> contained object a "value type".
>
No, it isn't. It's no different that `vector<T>` placing a moveable=20
requirement on `T`. It's no different than `vector<T>`'s copy constructor=
=20
placing a copyable requirement on `T`. And remember, in C++98/03,=20
`vector<T>` required copyability period; C++11 simply weakened that to=20
moveable.
Types that conceptually holds some other object will frequently have to=20
impose restrictions on those types. So too with `any`. The only difference=
=20
with `any` is that, because it isn't a template, it cannot statically=20
provide or remove the copy constructor based on what it stores. Either=20
`any` for every type is copyable, or `any` for no type is copyable. The=20
alternative to these is discussed below:
If this is determined by design, what is the reason? Just because "the=20
> standard library types are predominantly value types"? Well, I don't thin=
k=20
> `any` is designed for only holding "the standard library types".
> =20
>
>> If you believe that the standard should have a `shared_any`, then propos=
e=20
>> that. But `any` isn't going to change just because you want different=20
>> behavior.
>>
>
> No, I won't. It can't be `shared_any`, because of the semantics. An `any`=
=20
> object being copied is not shared with copied instance. The reason of=20
> insisting non-sharing as the default behavior of copy constructor in=20
> general is exactly what you have said, and I have no problems with it.
>
If you want `any` to be copyable, and you want it to be able to hold a=20
non-copyable type... what happens when you copy it if it holds a=20
non-copyable type? Should it throw some kind of exception?
Doing this makes `any` effectively a move-only type. Why? Because *nobody*=
=20
will want to copy it, since copying it may fail with an exception that they=
=20
cannot effectively recover from. So you may as well have a `unique_any`=20
which outright forbids the potentially dangerous copy operation.
Now, that being said, because `any` guarantees nothrow moving regardless of=
=20
what it stores, a lot of people will move their `any` objects around rather=
=20
than copying them, because copying can fail due to the stored object's copy=
=20
constructor throwing.
So the question is one of numbers. The number of people who genuinely *need=
*=20
to copy their `any`s vs. the number of people who genuinely need to store=
=20
non-copyable objects in `any`. And let's be frank: we have absolutely no=20
idea of the answer to either of these questions.
You can't look at `boost::any` code, since that type predates move support=
=20
in C++. It forced copyability for the same reason that C++98/03 `vector<T>`=
=20
did; it had no other choice. At the same time, the only person who seems to=
=20
have a problem with `any` requiring copyability is... you. So it's not like=
=20
there's been a great clamoring for change in the standard on this point.
So right now, nobody knows the answer. But `any` exists as it presently=20
does, and it does work for a lot of people. So the burden of proof that=20
this is a significant problem worthy of change is on you.
--=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/40c77f6e-35f6-44e5-8af4-bfd86e3841fa%40isocpp.or=
g.
------=_Part_568_1156305918.1461336720405
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, April 21, 2016 at 9:29:45 PM UTC-4, FrankHB19=
89 wrote:<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">=E5=
=9C=A8 2016=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 UTC+8=
=E4=B8=8A=E5=8D=8812:29:28=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<b=
lockquote 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 Wednesday, April =
20, 2016 at 11:05:24 PM UTC-4, FrankHB1989 wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">But type erasure is not about passing the va=
lues. These properties are <i>orthogonal</i>. Even if "any" is no=
t copyable (and even not movable), it can still be naturally used in specif=
ic ways.<br></div></blockquote><div><br>I'm not sure what your point is=
..<br><br>Nobody is claiming that different kinds of `any` types with differ=
ent properties will be useless. Nobody is claiming that type-erasure requir=
es a value type.<br><br>The point is that, because C++ is a value-oriented =
language, the standard library types are predominantly value types. So `any=
` being a value type is the right answer for C++ as a value-oriented langua=
ge.<br><br></div></div></blockquote><div>I know it clearly, as [any.class]/=
3 suggested even more specific to `any`.<br>=C2=A0<br></div><div>However, t=
o make `any` a "value type" is different to force the type of con=
tained object a "value type".</div></div></blockquote><div><br>No=
, it isn't. It's no different that `vector<T>` placing a move=
able requirement on `T`. It's no different than `vector<T>`'s=
copy constructor placing a copyable requirement on `T`. And remember, in C=
++98/03, `vector<T>` required copyability period; C++11 simply weaken=
ed that to moveable.<br><br>Types that conceptually holds some other object=
will frequently have to impose restrictions on those types. So too with `a=
ny`. The only difference with `any` is that, because it isn't a templat=
e, it cannot statically provide or remove the copy constructor based on wha=
t it stores. Either `any` for every type is copyable, or `any` for no type =
is copyable. The alternative to these is discussed below:<br><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> If this is =
determined by design, what is the reason? Just because "the standard l=
ibrary types are predominantly value types"? Well, I don't think `=
any` is designed for only holding "the standard library types".<b=
r>=C2=A0<br></div><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"ltr">=
<div>If you believe that the standard should have a `shared_any`, then prop=
ose that. But `any` isn't going to change just because you want differe=
nt behavior.<br></div></div></blockquote><div><br>No, I won't. It can&#=
39;t be `shared_any`, because of the semantics. An `any` object being copie=
d is not shared with copied instance. The reason of insisting non-sharing a=
s the default behavior of copy constructor in general is exactly what you h=
ave said, and I have no problems with it.<br></div></div></blockquote><div>=
<br>If you want `any` to be copyable, and you want it to be able to hold a =
non-copyable type... what happens when you copy it if it holds a non-copyab=
le type? Should it throw some kind of exception?<br><br>Doing this makes `a=
ny` effectively a move-only type. Why? Because <i>nobody</i> will want to c=
opy it, since copying it may fail with an exception that they cannot effect=
ively recover from. So you may as well have a `unique_any` which outright f=
orbids the potentially dangerous copy operation.<br><br>Now, that being sai=
d, because `any` guarantees nothrow moving regardless of what it stores, a =
lot of people will move their `any` objects around rather than copying them=
, because copying can fail due to the stored object's copy constructor =
throwing.<br><br>So the question is one of numbers. The number of people wh=
o genuinely <i>need</i> to copy their `any`s vs. the number of people who g=
enuinely need to store non-copyable objects in `any`. And let's be fran=
k: we have absolutely no idea of the answer to either of these questions.<b=
r><br>You can't look at `boost::any` code, since that type predates mov=
e support in C++. It forced copyability for the same reason that C++98/03 `=
vector<T>` did; it had no other choice. At the same time, the only pe=
rson who seems to have a problem with `any` requiring copyability is... you=
.. So it's not like there's been a great clamoring for change in the=
standard on this point.<br><br>So right now, nobody knows the answer. But =
`any` exists as it presently does, and it does work for a lot of people. So=
the burden of proof that this is a significant problem worthy of change is=
on you.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/40c77f6e-35f6-44e5-8af4-bfd86e3841fa%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/40c77f6e-35f6-44e5-8af4-bfd86e3841fa=
%40isocpp.org</a>.<br />
------=_Part_568_1156305918.1461336720405--
------=_Part_567_197410772.1461336720404--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 22 Apr 2016 12:40:22 -0500
Raw View
--001a113eca349d8f3d0531165494
Content-Type: text/plain; charset=UTF-8
On 22 April 2016 at 09:52, Nicol Bolas <jmckesson@gmail.com> wrote:
> No, it isn't. It's no different that `vector<T>` placing a moveable
> requirement on `T`.
>
But vector<T> does *not* place a moveable requirement on T. Certain
*operations* do (such as emplace_back), but a vector can hold a
non-moveable type, and that distinction matters. The following is
perfectly valid:
vector<NonMoveableType> v(100);
It's no different than `vector<T>`'s copy constructor placing a copyable
> requirement on `T`.
>
It is different, in that any puts the requirement on the type, even if you
never perform the operation. We have the same issue with std::function for
the same reason.
The language does not have a solution to this problem. Maybe once we have
runtime concepts...
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
--
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/CAGg_6%2BMxuTM373xB9Q_%2BHq3tcObyQNj%2Bn2cUXH5Dm_-3PsBUvA%40mail.gmail.com.
--001a113eca349d8f3d0531165494
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 22 April 2016 at 09:52, Nicol Bolas <span dir=3D"ltr">&=
lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail=
..com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmai=
l_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">No, it isn't. =
It's no different that `vector<T>` placing a moveable requirement=
on `T`. </div></blockquote><div><br></div><div>But vector<T> does <i=
>not</i> place a moveable requirement on T.=C2=A0 Certain <i>operations</i>=
do (such as emplace_back), but a vector can hold a non-moveable type, and =
that distinction matters.=C2=A0 The following is perfectly valid:</div><div=
><br></div><div>vector<NonMoveableType> v(100);</div><div><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr">It's no different than `=
vector<T>`'s copy constructor placing a copyable requirement on `=
T`.</div></blockquote><div><br></div><div>It is different, in that any puts=
the requirement on the type, even if you never perform the operation.=C2=
=A0 We have the same issue with std::function for the same reason.</div><di=
v><br></div><div>The language does not have a solution to this problem.=C2=
=A0 Maybe once we have runtime concepts...</div></div>-- <br><div class=3D"=
gmail_signature"><div dir=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin &q=
uot;:-)" Liber=C2=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.c=
om" target=3D"_blank">nevin@eviloverlord.com</a>> =C2=A0+1-847-691-1404<=
/div></div></div></div></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/CAGg_6%2BMxuTM373xB9Q_%2BHq3tcObyQNj%=
2Bn2cUXH5Dm_-3PsBUvA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BMx=
uTM373xB9Q_%2BHq3tcObyQNj%2Bn2cUXH5Dm_-3PsBUvA%40mail.gmail.com</a>.<br />
--001a113eca349d8f3d0531165494--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 22 Apr 2016 12:03:52 -0700 (PDT)
Raw View
------=_Part_1479_904028653.1461351832931
Content-Type: multipart/alternative;
boundary="----=_Part_1480_1625860533.1461351832931"
------=_Part_1480_1625860533.1461351832931
Content-Type: text/plain; charset=UTF-8
On Friday, April 22, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:
>
> On 22 April 2016 at 09:52, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
>
>> No, it isn't. It's no different that `vector<T>` placing a moveable
>> requirement on `T`.
>>
>
> But vector<T> does *not* place a moveable requirement on T. Certain
> *operations* do (such as emplace_back), but a vector can hold a
> non-moveable type, and that distinction matters. The following is
> perfectly valid:
>
> vector<NonMoveableType> v(100);
>
> It's no different than `vector<T>`'s copy constructor placing a copyable
>> requirement on `T`.
>>
>
> It is different, in that any puts the requirement on the type, even if you
> never perform the operation. We have the same issue with std::function for
> the same reason.
>
> The language does not have a solution to this problem. Maybe once we have
> runtime concepts...
>
.... how? Either you call the copy constructor or you don't; it's a static
property of how you used the type. Whatever "runtime concepts" may be, they
can't delete a function you actually call. The most that could happen is
attempting to call it would throw an exception, which is something we could
implement with `any` without any language changes.
Not that we should, of course.
--
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/0b1c11d7-5b82-47b2-976f-5e102e7e3662%40isocpp.org.
------=_Part_1480_1625860533.1461351832931
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, April 22, 2016 at 1:41:04 PM UTC-4, Nevin "=
;:-)" Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr">On 22 April 2016 at 09:52, Nicol Bolas <span dir=3D"ltr"><<a h=
ref=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"s4ObYRntBgAJ=
" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return =
true;" onclick=3D"this.href=3D'javascript:';return true;">jmck...@g=
mail.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr">No, it isn't. It's no differ=
ent that `vector<T>` placing a moveable requirement on `T`. </div></b=
lockquote><div><br></div><div>But vector<T> does <i>not</i> place a m=
oveable requirement on T.=C2=A0 Certain <i>operations</i> do (such as empla=
ce_back), but a vector can hold a non-moveable type, and that distinction m=
atters.=C2=A0 The following is perfectly valid:</div><div><br></div><div>ve=
ctor<NonMoveableType> v(100);</div><div><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">It's no different than `vector<T>`=
's copy constructor placing a copyable requirement on `T`.</div></block=
quote><div><br></div><div>It is different, in that any puts the requirement=
on the type, even if you never perform the operation.=C2=A0 We have the sa=
me issue with std::function for the same reason.</div><div><br></div><div>T=
he language does not have a solution to this problem.=C2=A0 Maybe once we h=
ave runtime concepts...<br></div></div></div></div></blockquote><div><br>..=
.. how? Either you call the copy constructor or you don't; it's a st=
atic property of how you used the type. Whatever "runtime concepts&quo=
t; may be, they can't delete a function you actually call. The most tha=
t could happen is attempting to call it would throw an exception, which is =
something we could implement with `any` without any language changes.<br><b=
r>Not that we should, of course.<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/0b1c11d7-5b82-47b2-976f-5e102e7e3662%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0b1c11d7-5b82-47b2-976f-5e102e7e3662=
%40isocpp.org</a>.<br />
------=_Part_1480_1625860533.1461351832931--
------=_Part_1479_904028653.1461351832931--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 22 Apr 2016 14:18:36 -0500
Raw View
--001a113e8e6ce95467053117b359
Content-Type: text/plain; charset=UTF-8
On 22 April 2016 at 14:03, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Friday, April 22, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:
>>
>> On 22 April 2016 at 09:52, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> No, it isn't. It's no different that `vector<T>` placing a moveable
>>> requirement on `T`.
>>>
>>
>> But vector<T> does *not* place a moveable requirement on T. Certain
>> *operations* do (such as emplace_back), but a vector can hold a
>> non-moveable type, and that distinction matters. The following is
>> perfectly valid:
>>
>> vector<NonMoveableType> v(100);
>>
>> It's no different than `vector<T>`'s copy constructor placing a copyable
>>> requirement on `T`.
>>>
>>
>> It is different, in that any puts the requirement on the type, even if
>> you never perform the operation. We have the same issue with std::function
>> for the same reason.
>>
>> The language does not have a solution to this problem. Maybe once we
>> have runtime concepts...
>>
>
> ... how? Either you call the copy constructor or you don't; it's a static
> property of how you used the type.
>
I can have a std::any or a std::function that I *never* copy, yet the
object it holds *must* have a copy constructor.
Right now, it is because type erasure under the hood has to generate a
virtual clone function or equivalent to perform the copy and that clone
function calls the copy constructor of the type it is holding. That clone
function is generated *even if there is no code written or generated to
ever call that copy function.*
That is a language-level limitation.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
--
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/CAGg_6%2BOO%2BP0OfUY_OaJ06W_CMi2MYyzmM1OWDNzCHNerK1ZkKA%40mail.gmail.com.
--001a113e8e6ce95467053117b359
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 22 April 2016 at 14:03, Nicol Bolas <span dir=3D"ltr">&=
lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail=
..com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmai=
l_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Friday, April 2=
2, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:<span><block=
quote 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 22 April 2016 at 09:5=
2, Nicol Bolas <span dir=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com<=
/a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">No, it isn't. It's no different that=
`vector<T>` placing a moveable requirement on `T`. </div></blockquot=
e><div><br></div><div>But vector<T> does <i>not</i> place a moveable =
requirement on T.=C2=A0 Certain <i>operations</i> do (such as emplace_back)=
, but a vector can hold a non-moveable type, and that distinction matters.=
=C2=A0 The following is perfectly valid:</div><div><br></div><div>vector<=
;NonMoveableType> v(100);</div><div><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr">It's no different than `vector<T>`'s co=
py constructor placing a copyable requirement on `T`.</div></blockquote><di=
v><br></div><div>It is different, in that any puts the requirement on the t=
ype, even if you never perform the operation.=C2=A0 We have the same issue =
with std::function for the same reason.</div><div><br></div><div>The langua=
ge does not have a solution to this problem.=C2=A0 Maybe once we have runti=
me concepts...<br></div></div></div></div></blockquote></span><div><br>... =
how? Either you call the copy constructor or you don't; it's a stat=
ic property of how you used the type. </div></div></blockquote><div><br></d=
iv><div>I can have a std::any or a std::function that I <i>never</i> copy, =
yet the object it holds <i>must</i> have a copy constructor.</div><div><br>=
</div><div>Right now, it is because type erasure under the hood has to gene=
rate a virtual clone function or equivalent to perform the copy and that cl=
one function calls the copy constructor of the type it is holding.=C2=A0 Th=
at clone function is generated=C2=A0<i>even if there is no code written or =
generated to ever call that copy=C2=A0function.</i></div><div><i><br></i></=
div><div>That is a language-level limitation.</div></div>-- <br><div><div d=
ir=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin ":-)" Liber=C2=
=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">=
nevin@eviloverlord.com</a>> =C2=A0<a href=3D"tel:%2B1-847-691-1404" valu=
e=3D"+18476911404" target=3D"_blank">+1-847-691-1404</a></div></div></div><=
/div></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/CAGg_6%2BOO%2BP0OfUY_OaJ06W_CMi2MYyzm=
M1OWDNzCHNerK1ZkKA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BOO%2=
BP0OfUY_OaJ06W_CMi2MYyzmM1OWDNzCHNerK1ZkKA%40mail.gmail.com</a>.<br />
--001a113e8e6ce95467053117b359--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Fri, 22 Apr 2016 19:05:37 -0700 (PDT)
Raw View
------=_Part_3300_1952035045.1461377137904
Content-Type: multipart/alternative;
boundary="----=_Part_3301_2079651506.1461377137905"
------=_Part_3301_2079651506.1461377137905
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 UTC=
+8=E4=B8=8B=E5=8D=8810:52:00=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Thursday, April 21, 2016 at 9:29:45 PM UTC-4, FrankHB1989 wrote:
>>
>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 =
UTC+8=E4=B8=8A=E5=8D=8812:29:28=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>>
>>> On Wednesday, April 20, 2016 at 11:05:24 PM UTC-4, FrankHB1989 wrote:
>>>>
>>>> But type erasure is not about passing the values. These properties are=
=20
>>>> *orthogonal*. Even if "any" is not copyable (and even not movable), it=
=20
>>>> can still be naturally used in specific ways.
>>>>
>>>
>>> I'm not sure what your point is.
>>>
>>> Nobody is claiming that different kinds of `any` types with different=
=20
>>> properties will be useless. Nobody is claiming that type-erasure requir=
es a=20
>>> value type.
>>>
>>> The point is that, because C++ is a value-oriented language, the=20
>>> standard library types are predominantly value types. So `any` being a=
=20
>>> value type is the right answer for C++ as a value-oriented language.
>>>
>>> I know it clearly, as [any.class]/3 suggested even more specific to=20
>> `any`.
>> =20
>> However, to make `any` a "value type" is different to force the type of=
=20
>> contained object a "value type".
>>
>
> No, it isn't. It's no different that `vector<T>` placing a moveable=20
> requirement on `T`. It's no different than `vector<T>`'s copy constructor=
=20
> placing a copyable requirement on `T`. And remember, in C++98/03,=20
> `vector<T>` required copyability period; C++11 simply weakened that to=20
> moveable.
>
> Types that conceptually holds some other object will frequently have to=
=20
> impose restrictions on those types. So too with `any`. The only differenc=
e=20
> with `any` is that, because it isn't a template, it cannot statically=20
> provide or remove the copy constructor based on what it stores. Either=20
> `any` for every type is copyable, or `any` for no type is copyable. The=
=20
> alternative to these is discussed below:
>
> No. The difference is `any` stores type-erased contained objects which ca=
n=20
be reified at runtime while `vector` dispatches no operation depending on=
=20
contained type at runtime.
=20
> If this is determined by design, what is the reason? Just because "the=20
>> standard library types are predominantly value types"? Well, I don't thi=
nk=20
>> `any` is designed for only holding "the standard library types".
>> =20
>>
>>> If you believe that the standard should have a `shared_any`, then=20
>>> propose that. But `any` isn't going to change just because you want=20
>>> different behavior.
>>>
>>
>> No, I won't. It can't be `shared_any`, because of the semantics. An `any=
`=20
>> object being copied is not shared with copied instance. The reason of=20
>> insisting non-sharing as the default behavior of copy constructor in=20
>> general is exactly what you have said, and I have no problems with it.
>>
>
> If you want `any` to be copyable, and you want it to be able to hold a=20
> non-copyable type... what happens when you copy it if it holds a=20
> non-copyable type? Should it throw some kind of exception?
>
> From this discussion on reddit=20
<https://www.reddit.com/r/cpp/comments/4fyt3v/why_doesnt_stdany_support_mov=
e_only_types/>,=20
there are several choices being noted. I think throwing is the only=20
acceptable one.
Doing this makes `any` effectively a move-only type.
>
No. The static type allows it to be copied, so it is not a move-only type.=
=20
The exceptional behavior at runtime is another topic.
=20
> Why? Because *nobody* will want to copy it, since copying it may fail=20
> with an exception that they cannot effectively recover from. So you may a=
s=20
> well have a `unique_any` which outright forbids the potentially dangerous=
=20
> copy operation.
>
> It is better to determine whether it can be copied or not statically, *on=
ly=20
when you can*. There are non-trivial cases that the static type cannot be=
=20
limited as I said previously. Taken this into account, separate=20
`unique_any` is not enough, because `unique_any` cannot replace `any`,=20
either. There could be a sum type of `any` and `unique_any` to cover both=
=20
set of use cases, but it is over-complicated.
I don't think it cannot effectively "recover from". How to recover? It=20
depends on the logic of client code. It can be in an exception flow within=
=20
a try block, when the Copyable property of the contained object is=20
determined at runtime. Even this is rarely needed, it does not harm other=
=20
use significantly, since the normal path should cost nothing in a modern=20
implementation. I don't think it will lose any significant optimization=20
opportunities because there has already almost no room to optimize such a=
=20
type-erased container in a static language without mandated additional=20
runtime to support re-evaluation of the code. I don't found it making=20
debugging significantly worse, either.
Also note this case is *not *a crash of the runtime of the language. This=
=20
is why I don't think calling `std::terminate` is acceptable.
=20
> Now, that being said, because `any` guarantees nothrow moving regardless=
=20
> of what it stores, a lot of people will move their `any` objects around=
=20
> rather than copying them, because copying can fail due to the stored=20
> object's copy constructor throwing.
>
> Is this different to the current status? The exception guarantees about=
=20
copying and moving of `any` itself need no changes.
=20
> So the question is one of numbers. The number of people who genuinely=20
> *need* to copy their `any`s vs. the number of people who genuinely need=
=20
> to store non-copyable objects in `any`. And let's be frank: we have=20
> absolutely no idea of the answer to either of these questions.
>
> That's irrelevant. Allowing to store non-copyable objects does not break=
=20
the ability of copy. If it does not work, it is the bug of client code.
When it should be one of the explicit constraints exposed by public APIs,=
=20
it still not have to be encoded statically. A similar scenario: do you=20
bother to add (dynamic) exception specifications *anywhere*? Even for=20
`noexcept`, there are sufficient reasons to avoid it in several cases.
=20
> You can't look at `boost::any` code, since that type predates move suppor=
t=20
> in C++. It forced copyability for the same reason that C++98/03 `vector<T=
>`=20
> did; it had no other choice. At the same time, the only person who seems =
to=20
> have a problem with `any` requiring copyability is... you. So it's not li=
ke=20
> there's been a great clamoring for change in the standard on this point.
>
> I looked at `boost::any` today and I found it did deal with the core=20
language changes. It seems to be lagged (e.g. operator=3D not fully=20
synchronized with recent papers). But the copyability ("ValueType" concept)=
=20
in the *documentation* was remained. I think it was still intentional.
=20
> So right now, nobody knows the answer. But `any` exists as it presently=
=20
> does, and it does work for a lot of people. So the burden of proof that=
=20
> this is a significant problem worthy of change is on you.
>
--=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/e9a72e06-59eb-4653-b26a-6d4cdbe63984%40isocpp.or=
g.
------=_Part_3301_2079651506.1461377137905
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=BA=94 UTC+8=E4=B8=8B=E5=8D=8810:52:00=EF=BC=8CNicol Bolas=
=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Thursday, April 21, 2016 at 9:29:45 PM UTC-4, FrankHB1989 =
wrote:<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">=E5=9C=A8 20=
16=E5=B9=B44=E6=9C=8822=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 UTC+8=E4=B8=8A=
=E5=8D=8812:29:28=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<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 Wednesday, April 20, 2016 =
at 11:05:24 PM UTC-4, FrankHB1989 wrote:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr">But type erasure is not about passing the values. The=
se properties are <i>orthogonal</i>. Even if "any" is not copyabl=
e (and even not movable), it can still be naturally used in specific ways.<=
br></div></blockquote><div><br>I'm not sure what your point is.<br><br>=
Nobody is claiming that different kinds of `any` types with different prope=
rties will be useless. Nobody is claiming that type-erasure requires a valu=
e type.<br><br>The point is that, because C++ is a value-oriented language,=
the standard library types are predominantly value types. So `any` being a=
value type is the right answer for C++ as a value-oriented language.<br><b=
r></div></div></blockquote><div>I know it clearly, as [any.class]/3 suggest=
ed even more specific to `any`.<br>=C2=A0<br></div><div>However, to make `a=
ny` a "value type" is different to force the type of contained ob=
ject a "value type".</div></div></blockquote><div><br>No, it isn&=
#39;t. It's no different that `vector<T>` placing a moveable requ=
irement on `T`. It's no different than `vector<T>`'s copy con=
structor placing a copyable requirement on `T`. And remember, in C++98/03, =
`vector<T>` required copyability period; C++11 simply weakened that t=
o moveable.<br><br>Types that conceptually holds some other object will fre=
quently have to impose restrictions on those types. So too with `any`. The =
only difference with `any` is that, because it isn't a template, it can=
not statically provide or remove the copy constructor based on what it stor=
es. Either `any` for every type is copyable, or `any` for no type is copyab=
le. The alternative to these is discussed below:<br><br></div></div></block=
quote><div>No. The difference is `any` stores type-erased contained objects=
which can be reified at runtime while `vector` dispatches no operation dep=
ending on contained type at runtime.<br>=C2=A0<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div> If this is determined by desi=
gn, what is the reason? Just because "the standard library types are p=
redominantly value types"? Well, I don't think `any` is designed f=
or only holding "the standard library types".<br>=C2=A0<br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>If you believ=
e that the standard should have a `shared_any`, then propose that. But `any=
` isn't going to change just because you want different behavior.<br></=
div></div></blockquote><div><br>No, I won't. It can't be `shared_an=
y`, because of the semantics. An `any` object being copied is not shared wi=
th copied instance. The reason of insisting non-sharing as the default beha=
vior of copy constructor in general is exactly what you have said, and I ha=
ve no problems with it.<br></div></div></blockquote><div><br>If you want `a=
ny` to be copyable, and you want it to be able to hold a non-copyable type.=
... what happens when you copy it if it holds a non-copyable type? Should it=
throw some kind of exception?<br><br></div></div></blockquote><div>From <a=
href=3D"https://www.reddit.com/r/cpp/comments/4fyt3v/why_doesnt_stdany_sup=
port_move_only_types/">this discussion on reddit</a>, there are several cho=
ices being noted. I think throwing is the only acceptable one.<br><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Doing t=
his makes `any` effectively a move-only type.</div></div></blockquote><div>=
No. The static type allows it to be copied, so it is not a move-only type. =
The exceptional behavior at runtime is another topic.<br>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Why? Because <=
i>nobody</i> will want to copy it, since copying it may fail with an except=
ion that they cannot effectively recover from. So you may as well have a `u=
nique_any` which outright forbids the potentially dangerous copy operation.=
<br><br></div></div></blockquote><div>It is better to determine whether it =
can be copied or not statically, <i>only when you can</i>. There are non-tr=
ivial cases that the static type cannot be limited as I said previously. Ta=
ken this into account, separate `unique_any` is not enough, because `unique=
_any` cannot replace `any`, either. There could be a sum type of `any` and =
`unique_any` to cover both set of use cases, but it is over-complicated.<br=
><br>I don't think it cannot effectively "recover from". How =
to recover? It depends on the logic of client code. It can be in an excepti=
on flow within a try block, when the Copyable property of the contained obj=
ect is determined at runtime. Even this is rarely needed, it does not harm =
other use significantly, since the normal path should cost nothing in a mod=
ern implementation. I don't think it will lose any significant optimiza=
tion opportunities because there has already almost no room to optimize suc=
h a type-erased container in a static language without mandated additional =
runtime to support re-evaluation of the code. I don't found it making d=
ebugging significantly worse, either.<br><br>Also note this case is <i>not =
</i>a crash of the runtime of the language. This is why I don't think c=
alling `std::terminate` is acceptable.<br>=C2=A0<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Now, that being said, bec=
ause `any` guarantees nothrow moving regardless of what it stores, a lot of=
people will move their `any` objects around rather than copying them, beca=
use copying can fail due to the stored object's copy constructor throwi=
ng.<br><br></div></div></blockquote><div>Is this different to the current s=
tatus? The exception guarantees about copying and moving of `any` itself ne=
ed no changes.<br>=C2=A0<br></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"><div>So the question is one of numbers. The number o=
f people who genuinely <i>need</i> to copy their `any`s vs. the number of p=
eople who genuinely need to store non-copyable objects in `any`. And let=
9;s be frank: we have absolutely no idea of the answer to either of these q=
uestions.<br><br></div></div></blockquote><div>That's irrelevant. Allow=
ing to store non-copyable objects does not break the ability of copy. If it=
does not work, it is the bug of client code.<br><br>When it should be one =
of the explicit constraints exposed by public APIs, it still not have to be=
encoded statically. A similar scenario: do you bother to add (dynamic) exc=
eption specifications <i>anywhere</i>? Even for `noexcept`, there are suffi=
cient reasons to avoid it in several cases.<br>=C2=A0<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>You can't look a=
t `boost::any` code, since that type predates move support in C++. It force=
d copyability for the same reason that C++98/03 `vector<T>` did; it h=
ad no other choice. At the same time, the only person who seems to have a p=
roblem with `any` requiring copyability is... you. So it's not like the=
re's been a great clamoring for change in the standard on this point.<b=
r><br></div></div></blockquote><div>I looked at `boost::any` today and I fo=
und it did deal with the core language changes. It seems to be lagged (e.g.=
operator=3D not fully synchronized with recent papers). But the copyabilit=
y ("ValueType" concept) in the <i>documentation</i> was remained.=
I think it was still intentional.<br>=C2=A0<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div>So right now, nobody knows th=
e answer. But `any` exists as it presently does, and it does work for a lot=
of people. So the burden of proof that this is a significant problem worth=
y of change is on you.<br></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/e9a72e06-59eb-4653-b26a-6d4cdbe63984%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e9a72e06-59eb-4653-b26a-6d4cdbe63984=
%40isocpp.org</a>.<br />
------=_Part_3301_2079651506.1461377137905--
------=_Part_3300_1952035045.1461377137904--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Fri, 22 Apr 2016 19:18:09 -0700 (PDT)
Raw View
------=_Part_142_1439992370.1461377890098
Content-Type: multipart/alternative;
boundary="----=_Part_143_1368531591.1461377890098"
------=_Part_143_1368531591.1461377890098
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD UTC=
+8=E4=B8=8A=E5=8D=883:19:19=EF=BC=8CNevin ":-)" Liber=E5=86=99=E9=81=93=EF=
=BC=9A
>
> On 22 April 2016 at 14:03, Nicol Bolas <jmck...@gmail.com <javascript:>>=
=20
> wrote:
>
>> On Friday, April 22, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:
>>>
>>> On 22 April 2016 at 09:52, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>>> No, it isn't. It's no different that `vector<T>` placing a moveable=20
>>>> requirement on `T`.=20
>>>>
>>>
>>> But vector<T> does *not* place a moveable requirement on T. Certain=20
>>> *operations* do (such as emplace_back), but a vector can hold a=20
>>> non-moveable type, and that distinction matters. The following is=20
>>> perfectly valid:
>>>
>>> vector<NonMoveableType> v(100);
>>>
>>> It's no different than `vector<T>`'s copy constructor placing a copyabl=
e=20
>>>> requirement on `T`.
>>>>
>>>
>>> It is different, in that any puts the requirement on the type, even if=
=20
>>> you never perform the operation. We have the same issue with std::func=
tion=20
>>> for the same reason.
>>>
>>> The language does not have a solution to this problem. Maybe once we=
=20
>>> have runtime concepts...
>>>
>>
>> ... how? Either you call the copy constructor or you don't; it's a stati=
c=20
>> property of how you used the type.=20
>>
>
> I can have a std::any or a std::function that I *never* copy, yet the=20
> object it holds *must* have a copy constructor.
>
> Right now, it is because type erasure under the hood has to generate a=20
> virtual clone function or equivalent to perform the copy and that clone=
=20
> function calls the copy constructor of the type it is holding. That clon=
e=20
> function is generated *even if there is no code written or generated to=
=20
> ever call that copy function.*
>
> That is a language-level limitation.
>
In theory, no. This type is in the standard library so it can be=20
implemented with black magic provided by the implementation, like builtins=
=20
to inform JIT compiler to generate the code only when needed.
But in practice, yes :( Not only the difficulties of the implementation,=20
but also other mess out of control of the language spec, e.g. ABI.
--=20
> Nevin ":-)" Liber <mailto:ne...@eviloverlord.com <javascript:>> =20
> +1-847-691-1404
>
--=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/758bb693-3c22-4faf-848b-7ce0f38ed9e2%40isocpp.or=
g.
------=_Part_143_1368531591.1461377890098
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=
=9F=E6=9C=9F=E5=85=AD UTC+8=E4=B8=8A=E5=8D=883:19:19=EF=BC=8CNevin ":-=
)" Liber=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr">On 22 April 2016 at 14:03, Nicol Bolas <span dir=
=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"YFIs1nXyBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascr=
ipt:';return true;" onclick=3D"this.href=3D'javascript:';return=
true;">jmck...@gmail.com</a>></span> wrote:<br><div><div class=3D"gmail=
_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Friday, April 22=
, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:<span><blockq=
uote 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 22 April 2016 at 09:52=
, Nicol Bolas <span dir=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com</=
a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">No, it isn't. It's no different that=
`vector<T>` placing a moveable requirement on `T`. </div></blockquot=
e><div><br></div><div>But vector<T> does <i>not</i> place a moveable =
requirement on T.=C2=A0 Certain <i>operations</i> do (such as emplace_back)=
, but a vector can hold a non-moveable type, and that distinction matters.=
=C2=A0 The following is perfectly valid:</div><div><br></div><div>vector<=
;NonMoveableType> v(100);</div><div><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr">It's no different than `vector<T>`'s co=
py constructor placing a copyable requirement on `T`.</div></blockquote><di=
v><br></div><div>It is different, in that any puts the requirement on the t=
ype, even if you never perform the operation.=C2=A0 We have the same issue =
with std::function for the same reason.</div><div><br></div><div>The langua=
ge does not have a solution to this problem.=C2=A0 Maybe once we have runti=
me concepts...<br></div></div></div></div></blockquote></span><div><br>... =
how? Either you call the copy constructor or you don't; it's a stat=
ic property of how you used the type. </div></div></blockquote><div><br></d=
iv><div>I can have a std::any or a std::function that I <i>never</i> copy, =
yet the object it holds <i>must</i> have a copy constructor.</div><div><br>=
</div><div>Right now, it is because type erasure under the hood has to gene=
rate a virtual clone function or equivalent to perform the copy and that cl=
one function calls the copy constructor of the type it is holding.=C2=A0 Th=
at clone function is generated=C2=A0<i>even if there is no code written or =
generated to ever call that copy=C2=A0function.</i></div><div><i><br></i></=
div><div>That is a language-level limitation.</div></div></div></div></bloc=
kquote><div>In theory, no. This type is in the standard library so it can b=
e implemented with black magic provided by the implementation, like builtin=
s to inform JIT compiler to generate the code only when needed.<br><br>But =
in practice, yes :( Not only the difficulties of the implementation, but al=
so other mess out of control of the language spec, e.g. ABI.<br><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>-- <br><d=
iv><div dir=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin ":-)" =
Liber=C2=A0 <mailto:<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"YFIs1nXyBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:';return true;" onclick=3D"this.href=3D'javascript:&#=
39;;return true;">ne...@eviloverlord.com</a><wbr>> =C2=A0<a value=3D"+18=
476911404">+1-847-691-1404</a></div></div></div></div></div>
</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/758bb693-3c22-4faf-848b-7ce0f38ed9e2%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/758bb693-3c22-4faf-848b-7ce0f38ed9e2=
%40isocpp.org</a>.<br />
------=_Part_143_1368531591.1461377890098--
------=_Part_142_1439992370.1461377890098--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 22 Apr 2016 22:05:10 -0700 (PDT)
Raw View
------=_Part_6_1525827681.1461387910745
Content-Type: multipart/alternative;
boundary="----=_Part_7_1267302080.1461387910745"
------=_Part_7_1267302080.1461387910745
Content-Type: text/plain; charset=UTF-8
On Friday, April 22, 2016 at 3:19:19 PM UTC-4, Nevin ":-)" Liber wrote:
>
> On 22 April 2016 at 14:03, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
>
>> On Friday, April 22, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:
>>>
>>> On 22 April 2016 at 09:52, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>>> No, it isn't. It's no different that `vector<T>` placing a moveable
>>>> requirement on `T`.
>>>>
>>>
>>> But vector<T> does *not* place a moveable requirement on T. Certain
>>> *operations* do (such as emplace_back), but a vector can hold a
>>> non-moveable type, and that distinction matters. The following is
>>> perfectly valid:
>>>
>>> vector<NonMoveableType> v(100);
>>>
>>> It's no different than `vector<T>`'s copy constructor placing a copyable
>>>> requirement on `T`.
>>>>
>>>
>>> It is different, in that any puts the requirement on the type, even if
>>> you never perform the operation. We have the same issue with std::function
>>> for the same reason.
>>>
>>> The language does not have a solution to this problem. Maybe once we
>>> have runtime concepts...
>>>
>>
>> ... how? Either you call the copy constructor or you don't; it's a static
>> property of how you used the type.
>>
>
> I can have a std::any or a std::function that I *never* copy, yet the
> object it holds *must* have a copy constructor.
>
Right. But there's no way for a *static property* of a type to know what
you're going to do with a *particular instance* of that type.
> Right now, it is because type erasure under the hood has to generate a
> virtual clone function or equivalent to perform the copy and that clone
> function calls the copy constructor of the type it is holding. That clone
> function is generated *even if there is no code written or generated to
> ever call that copy function.*
>
> That is a language-level limitation.
>
Only in the sense that C++ is statically typed. And that's not going to
change anytime soon.
--
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/bbbe4937-c591-4d8c-936d-f528f5191175%40isocpp.org.
------=_Part_7_1267302080.1461387910745
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, April 22, 2016 at 3:19:19 PM UTC-4, Nevin "=
;:-)" Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr">On 22 April 2016 at 14:03, Nicol Bolas <span dir=3D"ltr"><<a h=
ref=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"YFIs1nXyBgAJ=
" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return =
true;" onclick=3D"this.href=3D'javascript:';return true;">jmck...@g=
mail.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr">On Friday, April 22, 2016 at 1:41:04=
PM UTC-4, Nevin ":-)" Liber wrote:<span><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr">On 22 April 2016 at 09:52, Nicol Bolas <sp=
an dir=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com</a>></span> wro=
te:<br><div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr">No, it isn't. It's no different that `vector<T>` =
placing a moveable requirement on `T`. </div></blockquote><div><br></div><d=
iv>But vector<T> does <i>not</i> place a moveable requirement on T.=
=C2=A0 Certain <i>operations</i> do (such as emplace_back), but a vector ca=
n hold a non-moveable type, and that distinction matters.=C2=A0 The followi=
ng is perfectly valid:</div><div><br></div><div>vector<NonMoveableType&g=
t; v(100);</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">It's no different than `vector<T>`'s copy constructor pla=
cing a copyable requirement on `T`.</div></blockquote><div><br></div><div>I=
t is different, in that any puts the requirement on the type, even if you n=
ever perform the operation.=C2=A0 We have the same issue with std::function=
for the same reason.</div><div><br></div><div>The language does not have a=
solution to this problem.=C2=A0 Maybe once we have runtime concepts...<br>=
</div></div></div></div></blockquote></span><div><br>... how? Either you ca=
ll the copy constructor or you don't; it's a static property of how=
you used the type. </div></div></blockquote><div><br></div><div>I can have=
a std::any or a std::function that I <i>never</i> copy, yet the object it =
holds <i>must</i> have a copy constructor.</div></div></div></div></blockqu=
ote><div><br>Right. But there's no way for a <i>static property</i> of =
a type to know what you're going to do with a <i>particular instance</i=
> of that type.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div>Right now=
, it is because type erasure under the hood has to generate a virtual clone=
function or equivalent to perform the copy and that clone function calls t=
he copy constructor of the type it is holding.=C2=A0 That clone function is=
generated=C2=A0<i>even if there is no code written or generated to ever ca=
ll that copy=C2=A0function.</i></div><div><i><br></i></div><div>That is a l=
anguage-level limitation.</div></div></div></div></blockquote><div><br>Only=
in the sense that C++ is statically typed. And that's not going to cha=
nge anytime soon. <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/bbbe4937-c591-4d8c-936d-f528f5191175%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bbbe4937-c591-4d8c-936d-f528f5191175=
%40isocpp.org</a>.<br />
------=_Part_7_1267302080.1461387910745--
------=_Part_6_1525827681.1461387910745--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 22 Apr 2016 22:06:08 -0700 (PDT)
Raw View
------=_Part_2982_621183910.1461387968379
Content-Type: multipart/alternative;
boundary="----=_Part_2983_1676746079.1461387968379"
------=_Part_2983_1676746079.1461387968379
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, April 22, 2016 at 10:18:10 PM UTC-4, FrankHB1989 wrote:
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD U=
TC+8=E4=B8=8A=E5=8D=883:19:19=EF=BC=8CNevin ":-)" Liber=E5=86=99=E9=81=93=
=EF=BC=9A
>>
>> On 22 April 2016 at 14:03, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Friday, April 22, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:
>>>>
>>>> On 22 April 2016 at 09:52, Nicol Bolas <jmck...@gmail.com> wrote:
>>>>
>>>>> No, it isn't. It's no different that `vector<T>` placing a moveable=
=20
>>>>> requirement on `T`.=20
>>>>>
>>>>
>>>> But vector<T> does *not* place a moveable requirement on T. Certain=
=20
>>>> *operations* do (such as emplace_back), but a vector can hold a=20
>>>> non-moveable type, and that distinction matters. The following is=20
>>>> perfectly valid:
>>>>
>>>> vector<NonMoveableType> v(100);
>>>>
>>>> It's no different than `vector<T>`'s copy constructor placing a=20
>>>>> copyable requirement on `T`.
>>>>>
>>>>
>>>> It is different, in that any puts the requirement on the type, even if=
=20
>>>> you never perform the operation. We have the same issue with std::fun=
ction=20
>>>> for the same reason.
>>>>
>>>> The language does not have a solution to this problem. Maybe once we=
=20
>>>> have runtime concepts...
>>>>
>>>
>>> ... how? Either you call the copy constructor or you don't; it's a=20
>>> static property of how you used the type.=20
>>>
>>
>> I can have a std::any or a std::function that I *never* copy, yet the=20
>> object it holds *must* have a copy constructor.
>>
>> Right now, it is because type erasure under the hood has to generate a=
=20
>> virtual clone function or equivalent to perform the copy and that clone=
=20
>> function calls the copy constructor of the type it is holding. That clo=
ne=20
>> function is generated *even if there is no code written or generated to=
=20
>> ever call that copy function.*
>>
>> That is a language-level limitation.
>>
> In theory, no. This type is in the standard library so it can be=20
> implemented with black magic provided by the implementation, like builtin=
s=20
> to inform JIT compiler to generate the code only when needed.
>
There is no "black magic" that can turn a static property of a type into a=
=20
dynamic property of an instance.
--=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/5730a964-3b8f-401a-be28-6b078583200a%40isocpp.or=
g.
------=_Part_2983_1676746079.1461387968379
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, April 22, 2016 at 10:18:10 PM UTC-4, FrankHB198=
9 wrote:<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">=E5=
=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD UTC+8=
=E4=B8=8A=E5=8D=883:19:19=EF=BC=8CNevin ":-)" Liber=E5=86=99=E9=
=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On =
22 April 2016 at 14:03, Nicol Bolas <span dir=3D"ltr"><<a rel=3D"nofollo=
w">jmck...@gmail.com</a>></span> wrote:<br><div><div class=3D"gmail_quot=
e"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Friday, April 22, 201=
6 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote:<span><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 22 April 2016 at 09:52, Nic=
ol Bolas <span dir=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com</a>>=
;</span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr">No, it isn't. It's no different that `vecto=
r<T>` placing a moveable requirement on `T`. </div></blockquote><div>=
<br></div><div>But vector<T> does <i>not</i> place a moveable require=
ment on T.=C2=A0 Certain <i>operations</i> do (such as emplace_back), but a=
vector can hold a non-moveable type, and that distinction matters.=C2=A0 T=
he following is perfectly valid:</div><div><br></div><div>vector<NonMove=
ableType> v(100);</div><div><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr">It's no different than `vector<T>`'s copy const=
ructor placing a copyable requirement on `T`.</div></blockquote><div><br></=
div><div>It is different, in that any puts the requirement on the type, eve=
n if you never perform the operation.=C2=A0 We have the same issue with std=
::function for the same reason.</div><div><br></div><div>The language does =
not have a solution to this problem.=C2=A0 Maybe once we have runtime conce=
pts...<br></div></div></div></div></blockquote></span><div><br>... how? Eit=
her you call the copy constructor or you don't; it's a static prope=
rty of how you used the type. </div></div></blockquote><div><br></div><div>=
I can have a std::any or a std::function that I <i>never</i> copy, yet the =
object it holds <i>must</i> have a copy constructor.</div><div><br></div><d=
iv>Right now, it is because type erasure under the hood has to generate a v=
irtual clone function or equivalent to perform the copy and that clone func=
tion calls the copy constructor of the type it is holding.=C2=A0 That clone=
function is generated=C2=A0<i>even if there is no code written or generate=
d to ever call that copy=C2=A0function.</i></div><div><i><br></i></div><div=
>That is a language-level limitation.</div></div></div></div></blockquote><=
div>In theory, no. This type is in the standard library so it can be implem=
ented with black magic provided by the implementation, like builtins to inf=
orm JIT compiler to generate the code only when needed.<br></div></div></bl=
ockquote><div><br>There is no "black magic" that can turn a stati=
c property of a type into a dynamic property of an instance.</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/5730a964-3b8f-401a-be28-6b078583200a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5730a964-3b8f-401a-be28-6b078583200a=
%40isocpp.org</a>.<br />
------=_Part_2983_1676746079.1461387968379--
------=_Part_2982_621183910.1461387968379--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 22 Apr 2016 22:36:15 -0700 (PDT)
Raw View
------=_Part_2918_106838197.1461389775553
Content-Type: multipart/alternative;
boundary="----=_Part_2919_1965401949.1461389775554"
------=_Part_2919_1965401949.1461389775554
Content-Type: text/plain; charset=UTF-8
On Friday, April 22, 2016 at 10:05:37 PM UTC-4, FrankHB1989 wrote:
>
> If this is determined by design, what is the reason? Just because "the
>>> standard library types are predominantly value types"? Well, I don't think
>>> `any` is designed for only holding "the standard library types".
>>>
>>>
>>>> If you believe that the standard should have a `shared_any`, then
>>>> propose that. But `any` isn't going to change just because you want
>>>> different behavior.
>>>>
>>>
>>> No, I won't. It can't be `shared_any`, because of the semantics. An
>>> `any` object being copied is not shared with copied instance. The reason of
>>> insisting non-sharing as the default behavior of copy constructor in
>>> general is exactly what you have said, and I have no problems with it.
>>>
>>
>> If you want `any` to be copyable, and you want it to be able to hold a
>> non-copyable type... what happens when you copy it if it holds a
>> non-copyable type? Should it throw some kind of exception?
>>
>> From this discussion on reddit
> <https://www.reddit.com/r/cpp/comments/4fyt3v/why_doesnt_stdany_support_move_only_types/>,
> there are several choices being noted. I think throwing is the only
> acceptable one.
>
> Doing this makes `any` effectively a move-only type.
>>
> No. The static type allows it to be copied, so it is not a move-only type.
> The exceptional behavior at runtime is another topic.
>
I said "effectively". That is, it would be nearly universally used as if it
were a move-only type, with copying being a 1-in-100 feature that a rare
few would dare touch due to its fragility. It would become a de-facto
move-only type, even though it were technically permissible.
You may as well give it a `clone` member function.
Remember: one of the main use cases for `any` is for pass-through values.
That is, you have two systems A and B. A needs to pass an object to B. Both
A and B know what type it is. But they have to communicate by some
intermediate system K. And we don't want to hard-code the type being
passed, since K will be used for communication between many different
objects.
So the question is this: would you *ever* write K such that it would copy
an `any`, if you knew that copying could throw an exception just because
the `any` was given a non-copyable type? *Of course not.* You would go out
of your way to avoid writing K such that it copied the data. It would take
the `any` by `&&`, and it would move it into intermediate storage. And when
it gave it to B, it would either pass along a `const&` or transfer
ownership explicitly.
This also affects the design of K. If B needs to gain ownership of the
object, then K can only transfer that object *once*. Perfectly fine if K is
an event system, but if it's something more complex, where it may need to
call B multiple times, that becomes problematic. But at the same time,
you'll find a way around it. Why?
Because otherwise, you'd be writing K to be fragile, easily broken. After
all, K has *absolutely no way* of resolving such an error. The only one who
could resolve it is A, and K may well not copy the object until long after
A is finished registering the `any` with K.
So the safest course of action for implementing K is to make it avoid
copying `any`. That is, if `any`'s copy constructor was so fragile that it
would be guaranteed to fail for a whole slew of contained types.
Whereas if you know that all `any` objects will be copyable, then the only
reason to go out of your way to avoid copying it is if you were concerned
about the stored value throwing exceptions in its copy constructor.
Why? Because *nobody* will want to copy it, since copying it may fail with
>> an exception that they cannot effectively recover from. So you may as well
>> have a `unique_any` which outright forbids the potentially dangerous copy
>> operation.
>>
>> It is better to determine whether it can be copied or not statically, *only
> when you can*. There are non-trivial cases that the static type cannot be
> limited as I said previously. Taken this into account, separate
> `unique_any` is not enough, because `unique_any` cannot replace `any`,
> either.
>
Nonsense.
If a type can be put into an `any`, then it can be put into a `unique_any`.
So if you're in one of those "non-trivial cases" that you talk about, you
use `unique_any`. There's no need to have some ridiculous "sum type" of the
two.
You use the class that offers the features you need. And you never *need* a
type that can maybe be copied and maybe not.
> There could be a sum type of `any` and `unique_any` to cover both set of
> use cases, but it is over-complicated.
>
> I don't think it cannot effectively "recover from". How to recover? It
> depends on the logic of client code.
>
Generally speaking, if you needed a copy of something, you *needed a copy
of it*. You had some specific need to have two objects that had the same
data.
If you can't get that, most of the time the only answer is program
termination. At the very least, the local code performing the copy cannot
resolve the error.
It can be in an exception flow within a try block, when the Copyable
> property of the contained object is determined at runtime. Even this is
> rarely needed, it does not harm other use significantly, since the normal
> path should cost nothing in a modern implementation. I don't think it will
> lose any significant optimization opportunities because there has already
> almost no room to optimize such a type-erased container in a static
> language without mandated additional runtime to support re-evaluation of
> the code. I don't found it making debugging significantly worse, either.
>
.... I don't know where you're getting this "optimization" and "debugging"
stuff from. I'm talking about basic code logic no longer working.
If you have a `vector<T>` and you need to make a copy of it so that you can
perform some process on the copy (perhaps sorting it), and the copy
fails... you're SOL. Optimization and debugging don't matter because you *can't
do what you were trying to*. The only way to "recover" from this is to hope
that whomever is above you can recover from calling you.
Do you frequently catch `std::bad_alloc` in your code? While some people
do, most people don't. Because not being able to allocate memory represents
a failure mode that most code simply cannot correct or recover from.
I don't see a lot of people catching `std::couldnt_copy` or whatever that
`any` would throw for similar reasons. There just isn't a clean way to
recover from it locally, and globally, the use of an `any` is more often
than not an implementation detail that's irrelevant to the outer scope.
Also note this case is *not *a crash of the runtime of the language. This
> is why I don't think calling `std::terminate` is acceptable.
>
It's a crash when the uncaught exception hits `main`.
> Now, that being said, because `any` guarantees nothrow moving regardless
>> of what it stores, a lot of people will move their `any` objects around
>> rather than copying them, because copying can fail due to the stored
>> object's copy constructor throwing.
>>
>> Is this different to the current status? The exception guarantees about
> copying and moving of `any` itself need no changes.
>
>
>> So the question is one of numbers. The number of people who genuinely
>> *need* to copy their `any`s vs. the number of people who genuinely need
>> to store non-copyable objects in `any`. And let's be frank: we have
>> absolutely no idea of the answer to either of these questions.
>>
>> That's irrelevant.
>
Yes, it is relevant. You're asking for a change to be made to the nature of
a standard library type. Therefore, you need to justify that change.
If you could show that there is a great deal of need to be able to store
non-copyable objects in `any`, then you would have some justification for
your idea. Similarly, if we could show that the number of people who
genuinely need to copy their `any`'s is large, then making `any`'s copy
constructor fragile would hurt their ability to do what they need done.
--
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/99b48b7d-00ef-4b2e-8fe2-2f71ffd497ea%40isocpp.org.
------=_Part_2919_1965401949.1461389775554
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, April 22, 2016 at 10:05:37 PM UTC-4, FrankHB198=
9 wrote:<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"><div>=
</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"><div></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"><div> If this is de=
termined by design, what is the reason? Just because "the standard lib=
rary types are predominantly value types"? Well, I don't think `an=
y` is designed for only holding "the standard library types".<br>=
=C2=A0<br></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"><d=
iv>If you believe that the standard should have a `shared_any`, then propos=
e that. But `any` isn't going to change just because you want different=
behavior.<br></div></div></blockquote><div><br>No, I won't. It can'=
;t be `shared_any`, because of the semantics. An `any` object being copied =
is not shared with copied instance. The reason of insisting non-sharing as =
the default behavior of copy constructor in general is exactly what you hav=
e said, and I have no problems with it.<br></div></div></blockquote><div><b=
r>If you want `any` to be copyable, and you want it to be able to hold a no=
n-copyable type... what happens when you copy it if it holds a non-copyable=
type? Should it throw some kind of exception?<br><br></div></div></blockqu=
ote><div>From <a href=3D"https://www.reddit.com/r/cpp/comments/4fyt3v/why_d=
oesnt_stdany_support_move_only_types/" target=3D"_blank" rel=3D"nofollow" o=
nmousedown=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%=
2Fwww.reddit.com%2Fr%2Fcpp%2Fcomments%2F4fyt3v%2Fwhy_doesnt_stdany_support_=
move_only_types%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH29iXgIdTdHoQw45=
6Sr4ymMs-S1Q';return true;" onclick=3D"this.href=3D'https://www.goo=
gle.com/url?q\x3dhttps%3A%2F%2Fwww.reddit.com%2Fr%2Fcpp%2Fcomments%2F4fyt3v=
%2Fwhy_doesnt_stdany_support_move_only_types%2F\x26sa\x3dD\x26sntz\x3d1\x26=
usg\x3dAFQjCNH29iXgIdTdHoQw456Sr4ymMs-S1Q';return true;">this discussio=
n on reddit</a>, there are several choices being noted. I think throwing is=
the only acceptable one.<br><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div>Doing this makes `any` effectively a move-only ty=
pe.</div></div></blockquote><div>No. The static type allows it to be copied=
, so it is not a move-only type. The exceptional behavior at runtime is ano=
ther topic.<br></div></div></blockquote><div><br>I said "effectively&q=
uot;. That is, it would be nearly universally used as if it were a move-onl=
y type, with copying being a 1-in-100 feature that a rare few would dare to=
uch due to its fragility. It would become a de-facto move-only type, even t=
hough it were technically permissible.<br><br>You may as well give it a `cl=
one` member function.<br><br>Remember: one of the main use cases for `any` =
is for pass-through values. That is, you have two systems A and B. A needs =
to pass an object to B. Both A and B know what type it is. But they have to=
communicate by some intermediate system K. And we don't want to hard-c=
ode the type being passed, since K will be used for communication between m=
any different objects.<br><br>So the question is this: would you <i>ever</i=
> write K such that it would copy an `any`, if you knew that copying could =
throw an exception just because the `any` was given a non-copyable type? <i=
>Of course not.</i> You would go out of your way to avoid writing K such th=
at it copied the data. It would take the `any` by `&&`, and it woul=
d move it into intermediate storage. And when it gave it to B, it would eit=
her pass along a `const&` or transfer ownership explicitly.<br><br>This=
also affects the design of K. If B needs to gain ownership of the object, =
then K can only transfer that object *once*. Perfectly fine if K is an even=
t system, but if it's something more complex, where it may need to call=
B multiple times, that becomes problematic. But at the same time, you'=
ll find a way around it. Why?<br><br>Because otherwise, you'd be writin=
g K to be fragile, easily broken. After all, K has <i>absolutely no way</i>=
of resolving such an error. The only one who could resolve it is A, and K =
may well not copy the object until long after A is finished registering the=
`any` with K.<br><br>So the safest course of action for implementing K is =
to make it avoid copying `any`. That is, if `any`'s copy constructor wa=
s so fragile that it would be guaranteed to fail for a whole slew of contai=
ned types.<br><br>Whereas if you know that all `any` objects will be copyab=
le, then the only reason to go out of your way to avoid copying it is if yo=
u were concerned about the stored value throwing exceptions in its copy con=
structor.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div>Why? Because <i>nobody</i> will want to copy it, since copying it m=
ay fail with an exception that they cannot effectively recover from. So you=
may as well have a `unique_any` which outright forbids the potentially dan=
gerous copy operation.<br><br></div></div></blockquote><div>It is better to=
determine whether it can be copied or not statically, <i>only when you can=
</i>. There are non-trivial cases that the static type cannot be limited as=
I said previously. Taken this into account, separate `unique_any` is not e=
nough, because `unique_any` cannot replace `any`, either.</div></div></bloc=
kquote><div><br>Nonsense.<br><br>If a type can be put into an `any`, then i=
t can be put into a `unique_any`. So if you're in one of those "no=
n-trivial cases" that you talk about, you use `unique_any`. There'=
s no need to have some ridiculous "sum type" of the two.<br><br>Y=
ou use the class that offers the features you need. And you never <i>need</=
i> a type that can maybe be copied and maybe not.<br>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>There could be a s=
um type of `any` and `unique_any` to cover both set of use cases, but it is=
over-complicated.<br><br>I don't think it cannot effectively "rec=
over from". How to recover? It depends on the logic of client code.</d=
iv></div></blockquote><div><br>Generally speaking, if you needed a copy of =
something, you <i>needed a copy of it</i>. You had some specific need to ha=
ve two objects that had the same data.<br><br>If you can't get that, mo=
st of the time the only answer is program termination. At the very least, t=
he local code performing the copy cannot resolve the error.<br><br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> It can be=
in an exception flow within a try block, when the Copyable property of the=
contained object is determined at runtime. Even this is rarely needed, it =
does not harm other use significantly, since the normal path should cost no=
thing in a modern implementation. I don't think it will lose any signif=
icant optimization opportunities because there has already almost no room t=
o optimize such a type-erased container in a static language without mandat=
ed additional runtime to support re-evaluation of the code. I don't fou=
nd it making debugging significantly worse, either.<br></div></div></blockq=
uote><div><br>... I don't know where you're getting this "opti=
mization" and "debugging" stuff from. I'm talking about =
basic code logic no longer working.<br><br>If you have a `vector<T>` =
and you need to make a copy of it so that you can perform some process on t=
he copy (perhaps sorting it), and the copy fails... you're SOL. Optimiz=
ation and debugging don't matter because you <i>can't do what you w=
ere trying to</i>. The only way to "recover" from this is to hope=
that whomever is above you can recover from calling you.<br><br>Do you fre=
quently catch `std::bad_alloc` in your code? While some people do, most peo=
ple don't. Because not being able to allocate memory represents a failu=
re mode that most code simply cannot correct or recover from.<br><br>I don&=
#39;t see a lot of people catching `std::couldnt_copy` or whatever that `an=
y` would throw for similar reasons. There just isn't a clean way to rec=
over from it locally, and globally, the use of an `any` is more often than =
not an implementation detail that's irrelevant to the outer scope.<br><=
br></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"><div=
>Also note this case is <i>not </i>a crash of the runtime of the language. =
This is why I don't think calling `std::terminate` is acceptable.<br></=
div></div></blockquote><div><br>It's a crash when the uncaught exceptio=
n hits `main`.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>Now, that being said, because `any` guarantees nothrow movin=
g regardless of what it stores, a lot of people will move their `any` objec=
ts around rather than copying them, because copying can fail due to the sto=
red object's copy constructor throwing.<br><br></div></div></blockquote=
><div>Is this different to the current status? The exception guarantees abo=
ut copying and moving of `any` itself need no changes.<br>=C2=A0<br></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"><div>So the questio=
n is one of numbers. The number of people who genuinely <i>need</i> to copy=
their `any`s vs. the number of people who genuinely need to store non-copy=
able objects in `any`. And let's be frank: we have absolutely no idea o=
f the answer to either of these questions.<br><br></div></div></blockquote>=
<div>That's irrelevant.</div></div></blockquote><div><br>Yes, it is rel=
evant. You're asking for a change to be made to the nature of a standar=
d library type. Therefore, you need to justify that change.<br><br>If you c=
ould show that there is a great deal of need to be able to store non-copyab=
le objects in `any`, then you would have some justification for your idea. =
Similarly, if we could show that the number of people who genuinely need to=
copy their `any`'s is large, then making `any`'s copy constructor =
fragile would hurt their ability to do what they need done.<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/99b48b7d-00ef-4b2e-8fe2-2f71ffd497ea%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/99b48b7d-00ef-4b2e-8fe2-2f71ffd497ea=
%40isocpp.org</a>.<br />
------=_Part_2919_1965401949.1461389775554--
------=_Part_2918_106838197.1461389775553--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Sat, 23 Apr 2016 06:38:37 -0700 (PDT)
Raw View
------=_Part_3852_1671532394.1461418717677
Content-Type: multipart/alternative;
boundary="----=_Part_3853_1926946158.1461418717677"
------=_Part_3853_1926946158.1461418717677
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD UTC=
+8=E4=B8=8B=E5=8D=881:06:08=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Friday, April 22, 2016 at 10:18:10 PM UTC-4, FrankHB1989 wrote:
>>
>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD =
UTC+8=E4=B8=8A=E5=8D=883:19:19=EF=BC=8CNevin ":-)" Liber=E5=86=99=E9=81=93=
=EF=BC=9A
>>>
>>> On 22 April 2016 at 14:03, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>>> On Friday, April 22, 2016 at 1:41:04 PM UTC-4, Nevin ":-)" Liber wrote=
:
>>>>>
>>>>> On 22 April 2016 at 09:52, Nicol Bolas <jmck...@gmail.com> wrote:
>>>>>
>>>>>> No, it isn't. It's no different that `vector<T>` placing a moveable=
=20
>>>>>> requirement on `T`.=20
>>>>>>
>>>>>
>>>>> But vector<T> does *not* place a moveable requirement on T. Certain=
=20
>>>>> *operations* do (such as emplace_back), but a vector can hold a=20
>>>>> non-moveable type, and that distinction matters. The following is=20
>>>>> perfectly valid:
>>>>>
>>>>> vector<NonMoveableType> v(100);
>>>>>
>>>>> It's no different than `vector<T>`'s copy constructor placing a=20
>>>>>> copyable requirement on `T`.
>>>>>>
>>>>>
>>>>> It is different, in that any puts the requirement on the type, even i=
f=20
>>>>> you never perform the operation. We have the same issue with std::fu=
nction=20
>>>>> for the same reason.
>>>>>
>>>>> The language does not have a solution to this problem. Maybe once we=
=20
>>>>> have runtime concepts...
>>>>>
>>>>
>>>> ... how? Either you call the copy constructor or you don't; it's a=20
>>>> static property of how you used the type.=20
>>>>
>>>
>>> I can have a std::any or a std::function that I *never* copy, yet the=
=20
>>> object it holds *must* have a copy constructor.
>>>
>>> Right now, it is because type erasure under the hood has to generate a=
=20
>>> virtual clone function or equivalent to perform the copy and that clone=
=20
>>> function calls the copy constructor of the type it is holding. That cl=
one=20
>>> function is generated *even if there is no code written or generated to=
=20
>>> ever call that copy function.*
>>>
>>> That is a language-level limitation.
>>>
>> In theory, no. This type is in the standard library so it can be=20
>> implemented with black magic provided by the implementation, like builti=
ns=20
>> to inform JIT compiler to generate the code only when needed.
>>
>
> There is no "black magic" that can turn a static property of a type into =
a=20
> dynamic property of an instance.
>
There is no magic, but someone may think interpreters as magic.
If you talk about turning a dynamic property into a static one, that may=
=20
need more magic (e.g. partial evaluation).
--=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/6f4aacfe-2367-4c4e-803a-379204688111%40isocpp.or=
g.
------=_Part_3853_1926946158.1461418717677
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=
=9F=E6=9C=9F=E5=85=AD UTC+8=E4=B8=8B=E5=8D=881:06:08=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Friday, April 22, 2016 at 10:18:10 PM UTC-4, FrankHB1989 wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=E5=9C=A8 2016=
=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD UTC+8=E4=B8=8A=E5=
=8D=883:19:19=EF=BC=8CNevin ":-)" Liber=E5=86=99=E9=81=93=EF=BC=
=9A<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On 22 April 201=
6 at 14:03, Nicol Bolas <span dir=3D"ltr"><<a rel=3D"nofollow">jmck...@g=
mail.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr">On Friday, April 22, 2016 at 1:41:04=
PM UTC-4, Nevin ":-)" Liber wrote:<span><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr">On 22 April 2016 at 09:52, Nicol Bolas <sp=
an dir=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com</a>></span> wro=
te:<br><div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr">No, it isn't. It's no different that `vector<T>` =
placing a moveable requirement on `T`. </div></blockquote><div><br></div><d=
iv>But vector<T> does <i>not</i> place a moveable requirement on T.=
=C2=A0 Certain <i>operations</i> do (such as emplace_back), but a vector ca=
n hold a non-moveable type, and that distinction matters.=C2=A0 The followi=
ng is perfectly valid:</div><div><br></div><div>vector<NonMoveableType&g=
t; v(100);</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">It's no different than `vector<T>`'s copy constructor pla=
cing a copyable requirement on `T`.</div></blockquote><div><br></div><div>I=
t is different, in that any puts the requirement on the type, even if you n=
ever perform the operation.=C2=A0 We have the same issue with std::function=
for the same reason.</div><div><br></div><div>The language does not have a=
solution to this problem.=C2=A0 Maybe once we have runtime concepts...<br>=
</div></div></div></div></blockquote></span><div><br>... how? Either you ca=
ll the copy constructor or you don't; it's a static property of how=
you used the type. </div></div></blockquote><div><br></div><div>I can have=
a std::any or a std::function that I <i>never</i> copy, yet the object it =
holds <i>must</i> have a copy constructor.</div><div><br></div><div>Right n=
ow, it is because type erasure under the hood has to generate a virtual clo=
ne function or equivalent to perform the copy and that clone function calls=
the copy constructor of the type it is holding.=C2=A0 That clone function =
is generated=C2=A0<i>even if there is no code written or generated to ever =
call that copy=C2=A0function.</i></div><div><i><br></i></div><div>That is a=
language-level limitation.</div></div></div></div></blockquote><div>In the=
ory, no. This type is in the standard library so it can be implemented with=
black magic provided by the implementation, like builtins to inform JIT co=
mpiler to generate the code only when needed.<br></div></div></blockquote><=
div><br>There is no "black magic" that can turn a static property=
of a type into a dynamic property of an instance.</div></div></blockquote>=
<div>There is no magic, but someone may think interpreters as magic.<br>=C2=
=A0If you talk about turning a dynamic property into a static one, that may=
need more magic (e.g. partial evaluation).<br><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/6f4aacfe-2367-4c4e-803a-379204688111%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6f4aacfe-2367-4c4e-803a-379204688111=
%40isocpp.org</a>.<br />
------=_Part_3853_1926946158.1461418717677--
------=_Part_3852_1671532394.1461418717677--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Sat, 23 Apr 2016 07:36:18 -0700 (PDT)
Raw View
------=_Part_3728_2060092835.1461422178888
Content-Type: multipart/alternative;
boundary="----=_Part_3729_1084328782.1461422178888"
------=_Part_3729_1084328782.1461422178888
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD UTC=
+8=E4=B8=8B=E5=8D=881:36:15=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Friday, April 22, 2016 at 10:05:37 PM UTC-4, FrankHB1989 wrote:
>>
>> If this is determined by design, what is the reason? Just because "the=
=20
>>>> standard library types are predominantly value types"? Well, I don't t=
hink=20
>>>> `any` is designed for only holding "the standard library types".
>>>> =20
>>>>
>>>>> If you believe that the standard should have a `shared_any`, then=20
>>>>> propose that. But `any` isn't going to change just because you want=
=20
>>>>> different behavior.
>>>>>
>>>>
>>>> No, I won't. It can't be `shared_any`, because of the semantics. An=20
>>>> `any` object being copied is not shared with copied instance. The reas=
on of=20
>>>> insisting non-sharing as the default behavior of copy constructor in=
=20
>>>> general is exactly what you have said, and I have no problems with it.
>>>>
>>>
>>> If you want `any` to be copyable, and you want it to be able to hold a=
=20
>>> non-copyable type... what happens when you copy it if it holds a=20
>>> non-copyable type? Should it throw some kind of exception?
>>>
>>> From this discussion on reddit=20
>> <https://www.reddit.com/r/cpp/comments/4fyt3v/why_doesnt_stdany_support_=
move_only_types/>,=20
>> there are several choices being noted. I think throwing is the only=20
>> acceptable one.
>>
>> Doing this makes `any` effectively a move-only type.
>>>
>> No. The static type allows it to be copied, so it is not a move-only=20
>> type. The exceptional behavior at runtime is another topic.
>>
>
> I said "effectively". That is, it would be nearly universally used as if=
=20
> it were a move-only type, with copying being a 1-in-100 feature that a ra=
re=20
> few would dare touch due to its fragility. It would become a de-facto=20
> move-only type, even though it were technically permissible.
>
> You may as well give it a `clone` member function.
>
> Remember: one of the main use cases for `any` is for pass-through values.=
=20
> That is, you have two systems A and B. A needs to pass an object to B. Bo=
th=20
> A and B know what type it is. But they have to communicate by some=20
> intermediate system K. And we don't want to hard-code the type being=20
> passed, since K will be used for communication between many different=20
> objects.
>
> So the question is this: would you *ever* write K such that it would copy=
=20
> an `any`, if you knew that copying could throw an exception just because=
=20
> the `any` was given a non-copyable type? *Of course not.* You would go=20
> out of your way to avoid writing K such that it copied the data. It would=
=20
> take the `any` by `&&`, and it would move it into intermediate storage. A=
nd=20
> when it gave it to B, it would either pass along a `const&` or transfer=
=20
> ownership explicitly.
>
> This also affects the design of K. If B needs to gain ownership of the=20
> object, then K can only transfer that object *once*. Perfectly fine if K =
is=20
> an event system, but if it's something more complex, where it may need to=
=20
> call B multiple times, that becomes problematic. But at the same time,=20
> you'll find a way around it. Why?
>
> Because otherwise, you'd be writing K to be fragile, easily broken. After=
=20
> all, K has *absolutely no way* of resolving such an error. The only one=
=20
> who could resolve it is A, and K may well not copy the object until long=
=20
> after A is finished registering the `any` with K.
>
> So the safest course of action for implementing K is to make it avoid=20
> copying `any`. That is, if `any`'s copy constructor was so fragile that i=
t=20
> would be guaranteed to fail for a whole slew of contained types.
>
> Whereas if you know that all `any` objects will be copyable, then the onl=
y=20
> reason to go out of your way to avoid copying it is if you were concerned=
=20
> about the stored value throwing exceptions in its copy constructor.
>
> No. Introducing `any` as parameter types will easily cause performance=20
regressions since it can really hold *any *copyable objects, which is out=
=20
of my control at all. (Imagine how to tell the user don't put a big=20
container in it except for the documentation? And how to evaluate if it is=
=20
being violated?) So I will never use such a type without document=20
carefully. Even for totally statically typed function parameters there are=
=20
similar problems: will you take an arbitrary template type parameter `T`=20
(rather than `T&&` or `const T&`) as function parameter type of function=20
templates in general (except for well-known limited contexts like being an=
=20
iterator or a functor)?
Nevertheless, the use of being passed by value is not the killer feature of=
=20
`any` at first. To use it as a data member has no such problems. And I=20
doubt such random use of `any` being parameter type of public APIs will=20
lead to a bad design.
=20
> Why? Because *nobody* will want to copy it, since copying it may fail=20
>>> with an exception that they cannot effectively recover from. So you may=
as=20
>>> well have a `unique_any` which outright forbids the potentially dangero=
us=20
>>> copy operation.
>>>
>>> It is better to determine whether it can be copied or not statically, *=
only=20
>> when you can*. There are non-trivial cases that the static type cannot=
=20
>> be limited as I said previously. Taken this into account, separate=20
>> `unique_any` is not enough, because `unique_any` cannot replace `any`,=
=20
>> either.
>>
>
> Nonsense.
>
> If a type can be put into an `any`, then it can be put into a=20
> `unique_any`. So if you're in one of those "non-trivial cases" that you=
=20
> talk about, you use `unique_any`. There's no need to have some ridiculous=
=20
> "sum type" of the two.
>
> You use the class that offers the features you need. And you never *need*=
=20
> a type that can maybe be copied and maybe not.
> =20
>
>> There could be a sum type of `any` and `unique_any` to cover both set of=
=20
>> use cases, but it is over-complicated.
>>
>> I don't think it cannot effectively "recover from". How to recover? It=
=20
>> depends on the logic of client code.
>>
>
> Generally speaking, if you needed a copy of something, you *needed a copy=
=20
> of it*. You had some specific need to have two objects that had the same=
=20
> data.
>
> If you can't get that, most of the time the only answer is program=20
> termination. At the very least, the local code performing the copy cannot=
=20
> resolve the error.
>
> Yes, I can put it into a `unique_any`. But what if an `any` is needed=20
elsewhere (by some code not controlled by me)? Can `unique_ptr` with no=20
statically tagged type information be cast back to `any` without=20
significant cost in every cases? And if that can not be avoid, or should be=
=20
ignored ... then why not everyone just use `unique_any` and rename it to=20
`any`?
It is absurd to deliberately avoid additional dynamic logic based on the=20
current features provided by static typing. In fact, the mainstream=20
implementations of `any` do have such extra dynamic dispatching based on=20
switch statement or virtual function calls. Even if I can pretend I don't=
=20
need such features when providing interface, what if the client need it?=20
How do I (or the client) implement it without hack into the dirty=20
implementation details of the standard library? Or "any" is just designed=
=20
to be not usable here literally? Then it spoils a good name, and I have to=
=20
invent a new wheel replacing instead of reusing and extending it.
It can be in an exception flow within a try block, when the Copyable=20
>> property of the contained object is determined at runtime. Even this is=
=20
>> rarely needed, it does not harm other use significantly, since the norma=
l=20
>> path should cost nothing in a modern implementation. I don't think it wi=
ll=20
>> lose any significant optimization opportunities because there has alread=
y=20
>> almost no room to optimize such a type-erased container in a static=20
>> language without mandated additional runtime to support re-evaluation of=
=20
>> the code. I don't found it making debugging significantly worse, either.
>>
>
> ... I don't know where you're getting this "optimization" and "debugging"=
=20
> stuff from. I'm talking about basic code logic no longer working.
>
> I was searching for more (non existed) excuses then.
=20
> If you have a `vector<T>` and you need to make a copy of it so that you=
=20
> can perform some process on the copy (perhaps sorting it), and the copy=
=20
> fails... you're SOL. Optimization and debugging don't matter because you =
*can't=20
> do what you were trying to*. The only way to "recover" from this is to=20
> hope that whomever is above you can recover from calling you.
>
> Do you frequently catch `std::bad_alloc` in your code? While some people=
=20
> do, most people don't. Because not being able to allocate memory represen=
ts=20
> a failure mode that most code simply cannot correct or recover from.
>
> That's irrelevant. To catch `std::bad_alloc` without rethrowing it again=
=20
is generally illogical because there is no way to recover it, and you=20
should not swallow such a serious (at least) whole-program problem. That=20
"whomever is above you can recover from calling you" is out of the program=
=20
so there is nothing to do in the code.
On the other hand, exceptional state can be perfectly handled once the=20
client code figured out at which point it need to differentiate the need to=
=20
use copyable vs. noncopyable types. The "whomever is above you can recover=
=20
from calling you" is the client which calls the portion of code throwing=20
such exceptions.
=20
> I don't see a lot of people catching `std::couldnt_copy` or whatever that=
=20
> `any` would throw for similar reasons. There just isn't a clean way to=20
> recover from it locally, and globally, the use of an `any` is more often=
=20
> than not an implementation detail that's irrelevant to the outer scope.
>
> How is it not clean? I don't see it is not clean as other exceptions when=
=20
it *is *needed.
=20
> Also note this case is *not *a crash of the runtime of the language. This=
=20
>> is why I don't think calling `std::terminate` is acceptable.
>>
>
> It's a crash when the uncaught exception hits `main`.
> =20
>
Then it is a bug of the code using such features. It breaks the=20
precondition of the conditional (similar to noexcept operands depends on=20
some template type parmaeters) exception guarantees, so it should take this=
=20
risk.
..=20
> Now, that being said, because `any` guarantees nothrow moving regardless=
=20
>>> of what it stores, a lot of people will move their `any` objects around=
=20
>>> rather than copying them, because copying can fail due to the stored=20
>>> object's copy constructor throwing.
>>>
>>> Is this different to the current status? The exception guarantees about=
=20
>> copying and moving of `any` itself need no changes.
>> =20
>>
>>> So the question is one of numbers. The number of people who genuinely=
=20
>>> *need* to copy their `any`s vs. the number of people who genuinely need=
=20
>>> to store non-copyable objects in `any`. And let's be frank: we have=20
>>> absolutely no idea of the answer to either of these questions.
>>>
>>> That's irrelevant.
>>
>
> Yes, it is relevant. You're asking for a change to be made to the nature=
=20
> of a standard library type. Therefore, you need to justify that change.
>
> If you could show that there is a great deal of need to be able to store=
=20
> non-copyable objects in `any`, then you would have some justification for=
=20
> your idea. Similarly, if we could show that the number of people who=20
> genuinely need to copy their `any`'s is large, then making `any`'s copy=
=20
> constructor fragile would hurt their ability to do what they need done.
>
Before the ballot, let's gather the consensus first. Do you think "any" is=
=20
the right name, without any possible misconception to new users,=20
*absolutely*?
I don't think that is relevant to this point, particularly as there have=20
been people got surprised by the fact that `std::any` needs the contained=
=20
type to be copyable. Whether to change `std::any` or not at last, it=20
currently doesn't behave ideally.
--=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/b8be9a58-a610-43e9-aa01-e0c432e901d2%40isocpp.or=
g.
------=_Part_3729_1084328782.1461422178888
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=
=9F=E6=9C=9F=E5=85=AD UTC+8=E4=B8=8B=E5=8D=881:36:15=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Friday, April 22, 2016 at 10:05:37 PM UTC-4, FrankHB1989 wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></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"><div> If this is determined by=
design, what is the reason? Just because "the standard library types =
are predominantly value types"? Well, I don't think `any` is desig=
ned for only holding "the standard library types".<br>=C2=A0<br><=
/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"><div>If you b=
elieve that the standard should have a `shared_any`, then propose that. But=
`any` isn't going to change just because you want different behavior.<=
br></div></div></blockquote><div><br>No, I won't. It can't be `shar=
ed_any`, because of the semantics. An `any` object being copied is not shar=
ed with copied instance. The reason of insisting non-sharing as the default=
behavior of copy constructor in general is exactly what you have said, and=
I have no problems with it.<br></div></div></blockquote><div><br>If you wa=
nt `any` to be copyable, and you want it to be able to hold a non-copyable =
type... what happens when you copy it if it holds a non-copyable type? Shou=
ld it throw some kind of exception?<br><br></div></div></blockquote><div>Fr=
om <a href=3D"https://www.reddit.com/r/cpp/comments/4fyt3v/why_doesnt_stdan=
y_support_move_only_types/" rel=3D"nofollow" target=3D"_blank" onmousedown=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.redd=
it.com%2Fr%2Fcpp%2Fcomments%2F4fyt3v%2Fwhy_doesnt_stdany_support_move_only_=
types%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH29iXgIdTdHoQw456Sr4ymMs-S=
1Q';return true;" onclick=3D"this.href=3D'https://www.google.com/ur=
l?q\x3dhttps%3A%2F%2Fwww.reddit.com%2Fr%2Fcpp%2Fcomments%2F4fyt3v%2Fwhy_doe=
snt_stdany_support_move_only_types%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQ=
jCNH29iXgIdTdHoQw456Sr4ymMs-S1Q';return true;">this discussion on reddi=
t</a>, there are several choices being noted. I think throwing is the only =
acceptable one.<br><br></div><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>Doing this makes `any` effectively a move-only type.</div><=
/div></blockquote><div>No. The static type allows it to be copied, so it is=
not a move-only type. The exceptional behavior at runtime is another topic=
..<br></div></div></blockquote><div><br>I said "effectively". That=
is, it would be nearly universally used as if it were a move-only type, wi=
th copying being a 1-in-100 feature that a rare few would dare touch due to=
its fragility. It would become a de-facto move-only type, even though it w=
ere technically permissible.<br><br>You may as well give it a `clone` membe=
r function.<br><br>Remember: one of the main use cases for `any` is for pas=
s-through values. That is, you have two systems A and B. A needs to pass an=
object to B. Both A and B know what type it is. But they have to communica=
te by some intermediate system K. And we don't want to hard-code the ty=
pe being passed, since K will be used for communication between many differ=
ent objects.<br><br>So the question is this: would you <i>ever</i> write K =
such that it would copy an `any`, if you knew that copying could throw an e=
xception just because the `any` was given a non-copyable type? <i>Of course=
not.</i> You would go out of your way to avoid writing K such that it copi=
ed the data. It would take the `any` by `&&`, and it would move it =
into intermediate storage. And when it gave it to B, it would either pass a=
long a `const&` or transfer ownership explicitly.<br><br>This also affe=
cts the design of K. If B needs to gain ownership of the object, then K can=
only transfer that object *once*. Perfectly fine if K is an event system, =
but if it's something more complex, where it may need to call B multipl=
e times, that becomes problematic. But at the same time, you'll find a =
way around it. Why?<br><br>Because otherwise, you'd be writing K to be =
fragile, easily broken. After all, K has <i>absolutely no way</i> of resolv=
ing such an error. The only one who could resolve it is A, and K may well n=
ot copy the object until long after A is finished registering the `any` wit=
h K.<br><br>So the safest course of action for implementing K is to make it=
avoid copying `any`. That is, if `any`'s copy constructor was so fragi=
le that it would be guaranteed to fail for a whole slew of contained types.=
<br><br>Whereas if you know that all `any` objects will be copyable, then t=
he only reason to go out of your way to avoid copying it is if you were con=
cerned about the stored value throwing exceptions in its copy constructor.<=
br><br></div></div></blockquote><div>No. Introducing `any` as parameter typ=
es will easily cause performance regressions since it can really hold <i>an=
y </i>copyable objects, which is out of my control at all. (Imagine how to =
tell the user don't put a big container in it except for the documentat=
ion? And how to evaluate if it is being violated?) So I will never use such=
a type without document carefully. Even for totally statically typed funct=
ion parameters there are similar problems: will you take an arbitrary templ=
ate type parameter `T` (rather than `T&&` or `const T&`) as fun=
ction parameter type of function templates in general (except for well-know=
n limited contexts like being an iterator or a functor)?<br><br>Nevertheles=
s, the use of being passed by value is not the killer feature of `any` at f=
irst. To use it as a data member has no such problems. And I doubt such ran=
dom use of `any` being parameter type of public APIs will lead to a bad des=
ign.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>Why? Because <i>nobody</i> will want to copy it, since copying it may fai=
l with an exception that they cannot effectively recover from. So you may a=
s well have a `unique_any` which outright forbids the potentially dangerous=
copy operation.<br><br></div></div></blockquote><div>It is better to deter=
mine whether it can be copied or not statically, <i>only when you can</i>. =
There are non-trivial cases that the static type cannot be limited as I sai=
d previously. Taken this into account, separate `unique_any` is not enough,=
because `unique_any` cannot replace `any`, either.</div></div></blockquote=
><div><br>Nonsense.<br><br>If a type can be put into an `any`, then it can =
be put into a `unique_any`. So if you're in one of those "non-triv=
ial cases" that you talk about, you use `unique_any`. There's no n=
eed to have some ridiculous "sum type" of the two.<br><br>You use=
the class that offers the features you need. And you never <i>need</i> a t=
ype that can maybe be copied and maybe not.<br>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>There could be a sum type of =
`any` and `unique_any` to cover both set of use cases, but it is over-compl=
icated.<br><br>I don't think it cannot effectively "recover from&q=
uot;. How to recover? It depends on the logic of client code.</div></div></=
blockquote><div><br>Generally speaking, if you needed a copy of something, =
you <i>needed a copy of it</i>. You had some specific need to have two obje=
cts that had the same data.<br><br>If you can't get that, most of the t=
ime the only answer is program termination. At the very least, the local co=
de performing the copy cannot resolve the error.<br><br></div></div></block=
quote><div>=C2=A0Yes, I can put it into a `unique_any`. But what if an `any=
` is needed elsewhere (by some code not controlled by me)? Can `unique_ptr`=
with no statically tagged type information be cast back to `any` without s=
ignificant cost in every cases? And if that can not be avoid, or should be =
ignored ... then why not everyone just use `unique_any` and rename it to `a=
ny`?<br><br>It is absurd to deliberately avoid additional dynamic logic bas=
ed on the current features provided by static typing. In fact, the mainstre=
am implementations of `any` do have such extra dynamic dispatching based on=
switch statement or virtual function calls. Even if I can pretend I don=
9;t need such features when providing interface, what if the client need it=
? How do I (or the client) implement it without hack into the dirty impleme=
ntation details of the standard library? Or "any" is just designe=
d to be not usable here literally? Then it spoils a good name, and I have t=
o invent a new wheel replacing instead of reusing and extending it.<br><br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></=
div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div> It can b=
e in an exception flow within a try block, when the Copyable property of th=
e contained object is determined at runtime. Even this is rarely needed, it=
does not harm other use significantly, since the normal path should cost n=
othing in a modern implementation. I don't think it will lose any signi=
ficant optimization opportunities because there has already almost no room =
to optimize such a type-erased container in a static language without manda=
ted additional runtime to support re-evaluation of the code. I don't fo=
und it making debugging significantly worse, either.<br></div></div></block=
quote><div><br>... I don't know where you're getting this "opt=
imization" and "debugging" stuff from. I'm talking about=
basic code logic no longer working.<br><br></div></div></blockquote><div>I=
was searching for more (non existed) excuses then.<br>=C2=A0<br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>If you have =
a `vector<T>` and you need to make a copy of it so that you can perfo=
rm some process on the copy (perhaps sorting it), and the copy fails... you=
're SOL. Optimization and debugging don't matter because you <i>can=
't do what you were trying to</i>. The only way to "recover" =
from this is to hope that whomever is above you can recover from calling yo=
u.<br><br>Do you frequently catch `std::bad_alloc` in your code? While some=
people do, most people don't. Because not being able to allocate memor=
y represents a failure mode that most code simply cannot correct or recover=
from.<br><br></div></div></blockquote><div>That's irrelevant. To catch=
`std::bad_alloc` without rethrowing it again is generally illogical becaus=
e there is no way to recover it, and you should not swallow such a serious =
(at least) whole-program problem. That "whomever is above you can reco=
ver from calling you" is out of the program so there is nothing to do =
in the code.<br><br>On the other hand, exceptional state can be perfectly h=
andled once the client code figured out at which point it need to different=
iate the need to use copyable vs. noncopyable types. The "whomever is =
above you can recover from calling you" is the client which calls the =
portion of code throwing such exceptions.<br>=C2=A0<br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>I don't see a lot =
of people catching `std::couldnt_copy` or whatever that `any` would throw f=
or similar reasons. There just isn't a clean way to recover from it loc=
ally, and globally, the use of an `any` is more often than not an implement=
ation detail that's irrelevant to the outer scope.<br><br></div></div><=
/blockquote><div>How is it not clean? I don't see it is not clean as ot=
her exceptions when it <i>is </i>needed.<br>=C2=A0 <br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>Also note this case is <i>not=
</i>a crash of the runtime of the language. This is why I don't think =
calling `std::terminate` is acceptable.<br></div></div></blockquote><div><b=
r>It's a crash when the uncaught exception hits `main`.<br>=C2=A0</div>=
</div></blockquote><div>Then it is a bug of the code using such features. I=
t breaks the precondition of the conditional (similar to noexcept operands =
depends on some template type parmaeters) exception guarantees, so it shoul=
d take this risk.<br>. <br></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"><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></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
Now, that being said, because `any` guarantees nothrow moving regardless of=
what it stores, a lot of people will move their `any` objects around rathe=
r than copying them, because copying can fail due to the stored object'=
s copy constructor throwing.<br><br></div></div></blockquote><div>Is this d=
ifferent to the current status? The exception guarantees about copying and =
moving of `any` itself need no changes.<br>=C2=A0<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>So the question is one of num=
bers. The number of people who genuinely <i>need</i> to copy their `any`s v=
s. the number of people who genuinely need to store non-copyable objects in=
`any`. And let's be frank: we have absolutely no idea of the answer to=
either of these questions.<br><br></div></div></blockquote><div>That's=
irrelevant.</div></div></blockquote><div><br>Yes, it is relevant. You'=
re asking for a change to be made to the nature of a standard library type.=
Therefore, you need to justify that change.<br><br>If you could show that =
there is a great deal of need to be able to store non-copyable objects in `=
any`, then you would have some justification for your idea. Similarly, if w=
e could show that the number of people who genuinely need to copy their `an=
y`'s is large, then making `any`'s copy constructor fragile would h=
urt their ability to do what they need done.<br></div></div></blockquote><d=
iv>Before the ballot, let's gather the consensus first. Do you think &q=
uot;any" is the right name, without any possible misconception to new =
users, <i>absolutely</i>?<br>I don't think that is relevant to this poi=
nt, particularly as there have been people got surprised by the fact that `=
std::any` needs the contained type to be copyable. Whether to change `std::=
any` or not at last, it currently doesn't behave ideally.<br><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/b8be9a58-a610-43e9-aa01-e0c432e901d2%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b8be9a58-a610-43e9-aa01-e0c432e901d2=
%40isocpp.org</a>.<br />
------=_Part_3729_1084328782.1461422178888--
------=_Part_3728_2060092835.1461422178888--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 Apr 2016 20:36:18 -0700 (PDT)
Raw View
------=_Part_514_1464275073.1461468979015
Content-Type: multipart/alternative;
boundary="----=_Part_515_1212470475.1461468979016"
------=_Part_515_1212470475.1461468979016
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, April 23, 2016 at 10:36:18 AM UTC-4, FrankHB1989 wrote:
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD U=
TC+8=E4=B8=8B=E5=8D=881:36:15=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>> On Friday, April 22, 2016 at 10:05:37 PM UTC-4, FrankHB1989 wrote:
>>>
>>> If this is determined by design, what is the reason? Just because "the=
=20
>>>>> standard library types are predominantly value types"? Well, I don't =
think=20
>>>>> `any` is designed for only holding "the standard library types".
>>>>> =20
>>>>>
>>>>>> If you believe that the standard should have a `shared_any`, then=20
>>>>>> propose that. But `any` isn't going to change just because you want=
=20
>>>>>> different behavior.
>>>>>>
>>>>>
>>>>> No, I won't. It can't be `shared_any`, because of the semantics. An=
=20
>>>>> `any` object being copied is not shared with copied instance. The rea=
son of=20
>>>>> insisting non-sharing as the default behavior of copy constructor in=
=20
>>>>> general is exactly what you have said, and I have no problems with it=
..
>>>>>
>>>>
>>>> If you want `any` to be copyable, and you want it to be able to hold a=
=20
>>>> non-copyable type... what happens when you copy it if it holds a=20
>>>> non-copyable type? Should it throw some kind of exception?
>>>>
>>>> From this discussion on reddit=20
>>> <https://www.reddit.com/r/cpp/comments/4fyt3v/why_doesnt_stdany_support=
_move_only_types/>,=20
>>> there are several choices being noted. I think throwing is the only=20
>>> acceptable one.
>>>
>>> Doing this makes `any` effectively a move-only type.
>>>>
>>> No. The static type allows it to be copied, so it is not a move-only=20
>>> type. The exceptional behavior at runtime is another topic.
>>>
>>
>> I said "effectively". That is, it would be nearly universally used as if=
=20
>> it were a move-only type, with copying being a 1-in-100 feature that a r=
are=20
>> few would dare touch due to its fragility. It would become a de-facto=20
>> move-only type, even though it were technically permissible.
>>
>> You may as well give it a `clone` member function.
>>
>> Remember: one of the main use cases for `any` is for pass-through values=
..=20
>> That is, you have two systems A and B. A needs to pass an object to B. B=
oth=20
>> A and B know what type it is. But they have to communicate by some=20
>> intermediate system K. And we don't want to hard-code the type being=20
>> passed, since K will be used for communication between many different=20
>> objects.
>>
>> So the question is this: would you *ever* write K such that it would=20
>> copy an `any`, if you knew that copying could throw an exception just=20
>> because the `any` was given a non-copyable type? *Of course not.* You=20
>> would go out of your way to avoid writing K such that it copied the data=
..=20
>> It would take the `any` by `&&`, and it would move it into intermediate=
=20
>> storage. And when it gave it to B, it would either pass along a `const&`=
or=20
>> transfer ownership explicitly.
>>
>> This also affects the design of K. If B needs to gain ownership of the=
=20
>> object, then K can only transfer that object *once*. Perfectly fine if K=
is=20
>> an event system, but if it's something more complex, where it may need t=
o=20
>> call B multiple times, that becomes problematic. But at the same time,=
=20
>> you'll find a way around it. Why?
>>
>> Because otherwise, you'd be writing K to be fragile, easily broken. Afte=
r=20
>> all, K has *absolutely no way* of resolving such an error. The only one=
=20
>> who could resolve it is A, and K may well not copy the object until long=
=20
>> after A is finished registering the `any` with K.
>>
>> So the safest course of action for implementing K is to make it avoid=20
>> copying `any`. That is, if `any`'s copy constructor was so fragile that =
it=20
>> would be guaranteed to fail for a whole slew of contained types.
>>
>> Whereas if you know that all `any` objects will be copyable, then the=20
>> only reason to go out of your way to avoid copying it is if you were=20
>> concerned about the stored value throwing exceptions in its copy=20
>> constructor.
>>
>> No. Introducing `any` as parameter types will easily cause performance=
=20
> regressions since it can really hold *any *copyable objects, which is out=
=20
> of my control at all. (Imagine how to tell the user don't put a big=20
> container in it except for the documentation? And how to evaluate if it i=
s=20
> being violated?)
>
How exactly does that cause a performance regression? The alternative to=20
`any` is a `void*`. Which requires heap allocation (or keeping around a=20
pointer to a stack or global object). `void*` is not a value-type, so it's=
=20
impossible to copy it.
If you change your code from using `void*` to `any`, you would have no=20
reason to suddenly decide to start copying `any` objects. Since that's an=
=20
operation that wasn't available before. So in both cases, the big object=20
was heap allocated and in both cases, the object was not copied.
So where is the "performance regression"?
You would only get a "performance regression" if you completely changed the=
=20
nature of the code. And that would only happen if you aren't paying=20
attention to what you're doing.
Quite frankly, if you're not paying attention to what you're doing in C++,=
=20
you shouldn't be using the language.
So I will never use such a type without document carefully. Even for=20
> totally statically typed function parameters there are similar problems:=
=20
> will you take an arbitrary template type parameter `T` (rather than `T&&`=
=20
> or `const T&`) as function parameter type of function templates in genera=
l=20
> (except for well-known limited contexts like being an iterator or a=20
> functor)?
>
.... I probably wouldn't take an `any` value as a parameter either; I'd=20
either take a `const any&` or an `any&&`. What's your point?
Also, I think that such "well-known limited contexts" are poor choices too.=
=20
Particularly in modern times with move-only lambdas. I would hope that the=
=20
Ranges TS allows us to pass non-copyable functors to algorithms.
Nevertheless, the use of being passed by value is not the killer feature of=
=20
> `any` at first. To use it as a data member has no such problems.
>
It becomes a problem if it's a data member of a copyable type.
=20
> And I doubt such random use of `any` being parameter type of public APIs=
=20
> will lead to a bad design.
>
I don't know what you mean by "such random use of `any`". But I don't see=
=20
the need to use `any` "randomly".
`any` is a special-case type. It's a fine tool for its job, but that job is=
=20
not something you should encounter frequently. Indeed, I would consider=20
frequent use of `any` to be a code smell, an indicator that you're using=20
the wrong abstraction to solve a problem.
There could be a sum type of `any` and `unique_any` to cover both set of=20
>>> use cases, but it is over-complicated.
>>>
>>> I don't think it cannot effectively "recover from". How to recover? It=
=20
>>> depends on the logic of client code.
>>>
>>
>> Generally speaking, if you needed a copy of something, you *needed a=20
>> copy of it*. You had some specific need to have two objects that had the=
=20
>> same data.
>>
>> If you can't get that, most of the time the only answer is program=20
>> termination. At the very least, the local code performing the copy canno=
t=20
>> resolve the error.
>>
>> Yes, I can put it into a `unique_any`. But what if an `any` is needed=
=20
> elsewhere (by some code not controlled by me)? Can `unique_ptr` with no=
=20
> statically tagged type information be cast back to `any` without=20
> significant cost in every cases? And if that can not be avoid, or should =
be=20
> ignored ... then why not everyone just use `unique_any` and rename it to=
=20
> `any`?
>
Then you have finally reached my point.
`any` either should require the type to be copyable or `any` itself *should=
=20
not be copyable*. The half-measure you suggested, where `any` can be copied=
=20
and throw if what it contains cannot be copied, is worse than either=20
alternative.
It is absurd to deliberately avoid additional dynamic logic based on the=20
> current features provided by static typing. In fact, the mainstream=20
> implementations of `any` do have such extra dynamic dispatching based on=
=20
> switch statement or virtual function calls. Even if I can pretend I don't=
=20
> need such features when providing interface, what if the client need it?=
=20
> How do I (or the client) implement it without hack into the dirty=20
> implementation details of the standard library? Or "any" is just designed=
=20
> to be not usable here literally? Then it spoils a good name, and I have t=
o=20
> invent a new wheel replacing instead of reusing and extending it.
>
Not every type can be used by every person. No type fits every need. I'm=20
sure people would really like to be able to store non-copyable functors in=
=20
`std::function` too.
I know I would.
But that doesn't mean that `std::function` is the type that should allow=20
that.
If you have a `vector<T>` and you need to make a copy of it so that you can=
=20
>> perform some process on the copy (perhaps sorting it), and the copy=20
>> fails... you're SOL. Optimization and debugging don't matter because you=
*can't=20
>> do what you were trying to*. The only way to "recover" from this is to=
=20
>> hope that whomever is above you can recover from calling you.
>>
>> Do you frequently catch `std::bad_alloc` in your code? While some people=
=20
>> do, most people don't. Because not being able to allocate memory represe=
nts=20
>> a failure mode that most code simply cannot correct or recover from.
>>
>> That's irrelevant. To catch `std::bad_alloc` without rethrowing it again=
=20
> is generally illogical because there is no way to recover it, and you=20
> should not swallow such a serious (at least) whole-program problem. That=
=20
> "whomever is above you can recover from calling you" is out of the progra=
m=20
> so there is nothing to do in the code.
>
> On the other hand, exceptional state can be perfectly handled once the=20
> client code figured out at which point it need to differentiate the need =
to=20
> use copyable vs. noncopyable types. The "whomever is above you can recove=
r=20
> from calling you" is the client which calls the portion of code throwing=
=20
> such exceptions.
>
Unless that code is no longer on the stack, of course. As I pointed out, a=
=20
common use case for `any` will be intermediate value transfer. Once the=20
value is given, the code which did the wrong thing has already left the=20
call stack to do whatever. It is only at transfer time when the exception=
=20
would be thrown. By then, it's too late.
I don't see a lot of people catching `std::couldnt_copy` or whatever that=
=20
>> `any` would throw for similar reasons. There just isn't a clean way to=
=20
>> recover from it locally, and globally, the use of an `any` is more often=
=20
>> than not an implementation detail that's irrelevant to the outer scope.
>>
>> How is it not clean? I don't see it is not clean as other exceptions whe=
n=20
> it *is *needed.
>
It's as clean as `future`'s destructor that does different things based on=
=20
where the `future` came from=20
<http://en.cppreference.com/w/cpp/thread/future/~future>. If the `future`=
=20
came from an `async` call, then the destructor can block until the async=20
process is complete. If the `future` came from *anywhere else*, the=20
destructor will just detach itself from the async operation. Why did this=
=20
happen?
Because the designers of `async` wanted blocking behavior if you didn't=20
store the `future`. And much like you, they didn't want to introduce a new=
=20
`special_future_like_object` that would statically have specific behavior.
And in so doing, they created *chaos*.=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3630.pdf>
Having a class change its behavior in such a fundamental way, based solely=
=20
on how it was initialized, is not a "clean" method of coding. It makes it=
=20
very difficult to look at a piece of code and statically know if it is=20
reasonable.
Also, it should be noted that it wouldn't be difficult at all to create a=
=20
template wrapper type for non-copyable types, which will have a copy=20
constructor but will throw if you try to use it. That would give you most=
=20
of the effect you want.
You would need `make_noncopyable_any<T>` to create such an `any` (if `T` is=
=20
copyable, it won't wrap it). And you would need `noncopyable_any_cast<T>`=
=20
to cast it back (it would first try getting the wrapped `T`; if that=20
failed, it would try to get `T` directly. That allow `T` to be copyable).=
=20
Both of which can be written outside of the class.
So if you really, *truly* want this... you can still do it with `any` as it=
=20
currently stands.
So the question is one of numbers. The number of people who genuinely *need=
*=20
>>>> to copy their `any`s vs. the number of people who genuinely need to st=
ore=20
>>>> non-copyable objects in `any`. And let's be frank: we have absolutely =
no=20
>>>> idea of the answer to either of these questions.
>>>>
>>>> That's irrelevant.
>>>
>>
>> Yes, it is relevant. You're asking for a change to be made to the nature=
=20
>> of a standard library type. Therefore, you need to justify that change.
>>
>> If you could show that there is a great deal of need to be able to store=
=20
>> non-copyable objects in `any`, then you would have some justification fo=
r=20
>> your idea. Similarly, if we could show that the number of people who=20
>> genuinely need to copy their `any`'s is large, then making `any`'s copy=
=20
>> constructor fragile would hurt their ability to do what they need done.
>>
> Before the ballot, let's gather the consensus first. Do you think "any" i=
s=20
> the right name, without any possible misconception to new users,=20
> *absolutely*?
>
It fits right in with C++'s uniform initialization that isn't uniform,=20
perfect forwarding that isn't perfect, a `function` wrapper that can't wrap=
=20
every function, and a never-empty `variant` that can be empty.
C++ is *filled* with such things. Who will notice one more?
And quite frankly, an `any` that can't hold any type is far less misnamed=
=20
than our dynamic array class being named "vector".
Also, do you really want to argue "possible misconception to new users"?=20
Don't you think users will find it far more surprising that a type that is=
=20
supposedly copyable will emit an exception on copy for seemingly no reason?=
=20
Not to mention that such surprises will be *runtime errors*, rather than=20
compile-time failures...
By your own logic, either `any` as it stands or non-copyable `any` are more=
=20
"ideal" than a throw-on-copy `any`.
I don't think that is relevant to this point, particularly as there have=20
> been people got surprised by the fact that `std::any` needs the contained=
=20
> type to be copyable. Whether to change `std::any` or not at last, it=20
> currently doesn't behave ideally.
>
*C++ itself* doesn't behave ideally; why should we expect its types to do=
=20
so?
--=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/bd521a97-0d13-4c5e-9504-ee3e5e53a95d%40isocpp.or=
g.
------=_Part_515_1212470475.1461468979016
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, April 23, 2016 at 10:36:18 AM UTC-4, FrankHB1=
989 wrote:<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">=E5=
=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD UTC+8=
=E4=B8=8B=E5=8D=881:36:15=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Friday, April 22, =
2016 at 10:05:37 PM UTC-4, FrankHB1989 wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div> If this is determined by design, what is the reason? Jus=
t because "the standard library types are predominantly value types&qu=
ot;? Well, I don't think `any` is designed for only holding "the s=
tandard library types".<br>=C2=A0<br></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div>If you believe that the standard should =
have a `shared_any`, then propose that. But `any` isn't going to change=
just because you want different behavior.<br></div></div></blockquote><div=
><br>No, I won't. It can't be `shared_any`, because of the semantic=
s. An `any` object being copied is not shared with copied instance. The rea=
son of insisting non-sharing as the default behavior of copy constructor in=
general is exactly what you have said, and I have no problems with it.<br>=
</div></div></blockquote><div><br>If you want `any` to be copyable, and you=
want it to be able to hold a non-copyable type... what happens when you co=
py it if it holds a non-copyable type? Should it throw some kind of excepti=
on?<br><br></div></div></blockquote><div>From <a href=3D"https://www.reddit=
..com/r/cpp/comments/4fyt3v/why_doesnt_stdany_support_move_only_types/" rel=
=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'https://www=
..google.com/url?q\x3dhttps%3A%2F%2Fwww.reddit.com%2Fr%2Fcpp%2Fcomments%2F4f=
yt3v%2Fwhy_doesnt_stdany_support_move_only_types%2F\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNH29iXgIdTdHoQw456Sr4ymMs-S1Q';return true;" onclick=3D=
"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.reddit.=
com%2Fr%2Fcpp%2Fcomments%2F4fyt3v%2Fwhy_doesnt_stdany_support_move_only_typ=
es%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH29iXgIdTdHoQw456Sr4ymMs-S1Q&=
#39;;return true;">this discussion on reddit</a>, there are several choices=
being noted. I think throwing is the only acceptable one.<br><br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Doing this makes=
`any` effectively a move-only type.</div></div></blockquote><div>No. The s=
tatic type allows it to be copied, so it is not a move-only type. The excep=
tional behavior at runtime is another topic.<br></div></div></blockquote><d=
iv><br>I said "effectively". That is, it would be nearly universa=
lly used as if it were a move-only type, with copying being a 1-in-100 feat=
ure that a rare few would dare touch due to its fragility. It would become =
a de-facto move-only type, even though it were technically permissible.<br>=
<br>You may as well give it a `clone` member function.<br><br>Remember: one=
of the main use cases for `any` is for pass-through values. That is, you h=
ave two systems A and B. A needs to pass an object to B. Both A and B know =
what type it is. But they have to communicate by some intermediate system K=
.. And we don't want to hard-code the type being passed, since K will be=
used for communication between many different objects.<br><br>So the quest=
ion is this: would you <i>ever</i> write K such that it would copy an `any`=
, if you knew that copying could throw an exception just because the `any` =
was given a non-copyable type? <i>Of course not.</i> You would go out of yo=
ur way to avoid writing K such that it copied the data. It would take the `=
any` by `&&`, and it would move it into intermediate storage. And w=
hen it gave it to B, it would either pass along a `const&` or transfer =
ownership explicitly.<br><br>This also affects the design of K. If B needs =
to gain ownership of the object, then K can only transfer that object *once=
*. Perfectly fine if K is an event system, but if it's something more c=
omplex, where it may need to call B multiple times, that becomes problemati=
c. But at the same time, you'll find a way around it. Why?<br><br>Becau=
se otherwise, you'd be writing K to be fragile, easily broken. After al=
l, K has <i>absolutely no way</i> of resolving such an error. The only one =
who could resolve it is A, and K may well not copy the object until long af=
ter A is finished registering the `any` with K.<br><br>So the safest course=
of action for implementing K is to make it avoid copying `any`. That is, i=
f `any`'s copy constructor was so fragile that it would be guaranteed t=
o fail for a whole slew of contained types.<br><br>Whereas if you know that=
all `any` objects will be copyable, then the only reason to go out of your=
way to avoid copying it is if you were concerned about the stored value th=
rowing exceptions in its copy constructor.<br><br></div></div></blockquote>=
<div>No. Introducing `any` as parameter types will easily cause performance=
regressions since it can really hold <i>any </i>copyable objects, which is=
out of my control at all. (Imagine how to tell the user don't put a bi=
g container in it except for the documentation? And how to evaluate if it i=
s being violated?)</div></div></blockquote><div><br>How exactly does that c=
ause a performance regression? The alternative to `any` is a `void*`. Which=
requires heap allocation (or keeping around a pointer to a stack or global=
object). `void*` is not a value-type, so it's impossible to copy it.<b=
r><br>If you change your code from using `void*` to `any`, you would have n=
o reason to suddenly decide to start copying `any` objects. Since that'=
s an operation that wasn't available before. So in both cases, the big =
object was heap allocated and in both cases, the object was not copied.<br>=
<br>So where is the "performance regression"?<br><br>You would on=
ly get a "performance regression" if you completely changed the n=
ature of the code. And that would only happen if you aren't paying atte=
ntion to what you're doing.<br><br>Quite frankly, if you're not pay=
ing attention to what you're doing in C++, you shouldn't be using t=
he language.<br><br></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"><div>So I will never use such a type without document carefull=
y. Even for totally statically typed function parameters there are similar =
problems: will you take an arbitrary template type parameter `T` (rather th=
an `T&&` or `const T&`) as function parameter type of function =
templates in general (except for well-known limited contexts like being an =
iterator or a functor)?<br></div></div></blockquote><div><br>... I probably=
wouldn't take an `any` value as a parameter either; I'd either tak=
e a `const any&` or an `any&&`. What's your point?<br><br>A=
lso, I think that such "well-known limited contexts" are poor cho=
ices too. Particularly in modern times with move-only lambdas. I would hope=
that the Ranges TS allows us to pass non-copyable functors to algorithms.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div>Nevertheless, the use of being passed by value is not the killer featu=
re of `any` at first. To use it as a data member has no such problems.</div=
></div></blockquote><div><br>It becomes a problem if it's a data member=
of a copyable type.<br>=C2=A0</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"><div>And I doubt such random use of `any` being para=
meter type of public APIs will lead to a bad design.<br></div></div></block=
quote><div><br>I don't know what you mean by "such random use of `=
any`". But I don't see the need to use `any` "randomly".=
<br><br>`any` is a special-case type. It's a fine tool for its job, but=
that job is not something you should encounter frequently. Indeed, I would=
consider frequent use of `any` to be a code smell, an indicator that you&#=
39;re using the wrong abstraction to solve a problem.<br><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div></div></blockquote><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div>There could be a sum type of `any` and `u=
nique_any` to cover both set of use cases, but it is over-complicated.<br><=
br>I don't think it cannot effectively "recover from". How to=
recover? It depends on the logic of client code.</div></div></blockquote><=
div><br>Generally speaking, if you needed a copy of something, you <i>neede=
d a copy of it</i>. You had some specific need to have two objects that had=
the same data.<br><br>If you can't get that, most of the time the only=
answer is program termination. At the very least, the local code performin=
g the copy cannot resolve the error.<br><br></div></div></blockquote><div>=
=C2=A0Yes, I can put it into a `unique_any`. But what if an `any` is needed=
elsewhere (by some code not controlled by me)? Can `unique_ptr` with no st=
atically tagged type information be cast back to `any` without significant =
cost in every cases? And if that can not be avoid, or should be ignored ...=
then why not everyone just use `unique_any` and rename it to `any`?<br></d=
iv></div></blockquote><div><br>Then you have finally reached my point.<br><=
br>`any` either should require the type to be copyable or `any` itself=C2=
=A0<i></i><i>should not be copyable</i>. The half-measure you suggested, wh=
ere `any` can be copied and throw if what it contains cannot be copied, is =
worse than either alternative.<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div>It is absurd to deliberately avoid addi=
tional dynamic logic based on the current features provided by static typin=
g. In fact, the mainstream implementations of `any` do have such extra dyna=
mic dispatching based on switch statement or virtual function calls. Even i=
f I can pretend I don't need such features when providing interface, wh=
at if the client need it? How do I (or the client) implement it without hac=
k into the dirty implementation details of the standard library? Or "a=
ny" is just designed to be not usable here literally? Then it spoils a=
good name, and I have to invent a new wheel replacing instead of reusing a=
nd extending it.<br></div></div></blockquote><div><br>Not every type can be=
used by every person. No type fits every need. I'm sure people would r=
eally like to be able to store non-copyable functors in `std::function` too=
..<br><br>I know I would.<br><br>But that doesn't mean that `std::functi=
on` is the type that should allow that.<br><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>If you have a `vector<T>` and y=
ou need to make a copy of it so that you can perform some process on the co=
py (perhaps sorting it), and the copy fails... you're SOL. Optimization=
and debugging don't matter because you <i>can't do what you were t=
rying to</i>. The only way to "recover" from this is to hope that=
whomever is above you can recover from calling you.<br><br>Do you frequent=
ly catch `std::bad_alloc` in your code? While some people do, most people d=
on't. Because not being able to allocate memory represents a failure mo=
de that most code simply cannot correct or recover from.<br><br></div></div=
></blockquote><div>That's irrelevant. To catch `std::bad_alloc` without=
rethrowing it again is generally illogical because there is no way to reco=
ver it, and you should not swallow such a serious (at least) whole-program =
problem. That "whomever is above you can recover from calling you"=
; is out of the program so there is nothing to do in the code.<br><br>On th=
e other hand, exceptional state can be perfectly handled once the client co=
de figured out at which point it need to differentiate the need to use copy=
able vs. noncopyable types. The "whomever is above you can recover fro=
m calling you" is the client which calls the portion of code throwing =
such exceptions.<br></div></div></blockquote><div><br>Unless that code is n=
o longer on the stack, of course. As I pointed out, a common use case for `=
any` will be intermediate value transfer. Once the value is given, the code=
which did the wrong thing has already left the call stack to do whatever. =
It is only at transfer time when the exception would be thrown. By then, it=
's too late.<br><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>I don't see a lot of people catching `std::couldnt_copy`=
or whatever that `any` would throw for similar reasons. There just isn'=
;t a clean way to recover from it locally, and globally, the use of an `any=
` is more often than not an implementation detail that's irrelevant to =
the outer scope.<br><br></div></div></blockquote><div>How is it not clean? =
I don't see it is not clean as other exceptions when it <i>is </i>neede=
d.<br></div></div></blockquote><div><br>It's as clean as `future`'s=
destructor that <a href=3D"http://en.cppreference.com/w/cpp/thread/future/=
~future">does different things based on where the `future` came from</a>. I=
f the `future` came from an `async` call, then the destructor can block unt=
il the async process is complete. If the `future` came from <i>anywhere els=
e</i>, the destructor will just detach itself from the async operation. Why=
did this happen?<br><br>Because the designers of `async` wanted blocking b=
ehavior if you didn't store the `future`. And much like you, they didn&=
#39;t want to introduce a new `special_future_like_object` that would stati=
cally have specific behavior.<br><br>And in so doing, <a href=3D"http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3630.pdf">they created <i>ch=
aos</i>.</a><br><br>Having a class change its behavior in such a fundamenta=
l way, based solely on how it was initialized, is not a "clean" m=
ethod of coding. It makes it very difficult to look at a piece of code and =
statically know if it is reasonable.<br><br>Also, it should be noted that i=
t wouldn't be difficult at all to create a template wrapper type for no=
n-copyable types, which will have a copy constructor but will throw if you =
try to use it. That would give you most of the effect you want.<br><br>You =
would need `make_noncopyable_any<T>` to create such an `any` (if `T` =
is copyable, it won't wrap it). And you would need `noncopyable_any_cas=
t<T>` to cast it back (it would first try getting the wrapped `T`; if=
that failed, it would try to get `T` directly. That allow `T` to be copyab=
le). Both of which can be written outside of the class.<br><br>So if you re=
ally, <i>truly</i> want this... you can still do it with `any` as it curren=
tly stands.<br></div><div><br></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"><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"><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"><div></div><d=
iv></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"><div>So t=
he question is one of numbers. The number of people who genuinely <i>need</=
i> to copy their `any`s vs. the number of people who genuinely need to stor=
e non-copyable objects in `any`. And let's be frank: we have absolutely=
no idea of the answer to either of these questions.<br><br></div></div></b=
lockquote><div>That's irrelevant.</div></div></blockquote><div><br>Yes,=
it is relevant. You're asking for a change to be made to the nature of=
a standard library type. Therefore, you need to justify that change.<br><b=
r>If you could show that there is a great deal of need to be able to store =
non-copyable objects in `any`, then you would have some justification for y=
our idea. Similarly, if we could show that the number of people who genuine=
ly need to copy their `any`'s is large, then making `any`'s copy co=
nstructor fragile would hurt their ability to do what they need done.<br></=
div></div></blockquote><div>Before the ballot, let's gather the consens=
us first. Do you think "any" is the right name, without any possi=
ble misconception to new users, <i>absolutely</i>?<br></div></div></blockqu=
ote><div><br>It fits right in with C++'s uniform initialization that is=
n't uniform, perfect forwarding that isn't perfect, a `function` wr=
apper that can't wrap every function, and a never-empty `variant` that =
can be empty.<br><br>C++ is <i>filled</i> with such things. Who will notice=
one more?<br><br>And quite frankly, an `any` that can't hold any type =
is far less misnamed than our dynamic array class being named "vector&=
quot;.<br><br>Also, do you really want to argue "possible misconceptio=
n to new users"? Don't you think users will find it far more surpr=
ising that a type that is supposedly copyable will emit an exception on cop=
y for seemingly no reason? Not to mention that such surprises will be <i>ru=
ntime errors</i>, rather than compile-time failures...<br><br>By your own l=
ogic, either `any` as it stands or non-copyable `any` are more "ideal&=
quot; than a throw-on-copy `any`.<br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div>I don't think that is relevant t=
o this point, particularly as there have been people got surprised by the f=
act that `std::any` needs the contained type to be copyable. Whether to cha=
nge `std::any` or not at last, it currently doesn't behave ideally.<br>=
</div></div></blockquote><div><br><i>C++ itself</i> doesn't behave idea=
lly; why should we expect its types to do so?<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/bd521a97-0d13-4c5e-9504-ee3e5e53a95d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bd521a97-0d13-4c5e-9504-ee3e5e53a95d=
%40isocpp.org</a>.<br />
------=_Part_515_1212470475.1461468979016--
------=_Part_514_1464275073.1461468979015--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Mon, 25 Apr 2016 04:29:07 -0700 (PDT)
Raw View
------=_Part_5511_669475143.1461583747309
Content-Type: multipart/alternative;
boundary="----=_Part_5512_866302408.1461583747310"
------=_Part_5512_866302408.1461583747310
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5 UTC=
+8=E4=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Saturday, April 23, 2016 at 10:36:18 AM UTC-4, FrankHB1989 wrote:
>>
>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD =
UTC+8=E4=B8=8B=E5=8D=881:36:15=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>>
>>> On Friday, April 22, 2016 at 10:05:37 PM UTC-4, FrankHB1989 wrote:
>>>>
>>>> If this is determined by design, what is the reason? Just because "the=
=20
>>>>>> standard library types are predominantly value types"? Well, I don't=
think=20
>>>>>> `any` is designed for only holding "the standard library types".
>>>>>> =20
>>>>>>
>>>>>>> If you believe that the standard should have a `shared_any`, then=
=20
>>>>>>> propose that. But `any` isn't going to change just because you want=
=20
>>>>>>> different behavior.
>>>>>>>
>>>>>>
>>>>>> No, I won't. It can't be `shared_any`, because of the semantics. An=
=20
>>>>>> `any` object being copied is not shared with copied instance. The re=
ason of=20
>>>>>> insisting non-sharing as the default behavior of copy constructor in=
=20
>>>>>> general is exactly what you have said, and I have no problems with i=
t.
>>>>>>
>>>>>
>>>>> If you want `any` to be copyable, and you want it to be able to hold =
a=20
>>>>> non-copyable type... what happens when you copy it if it holds a=20
>>>>> non-copyable type? Should it throw some kind of exception?
>>>>>
>>>>> From this discussion on reddit=20
>>>> <https://www.reddit.com/r/cpp/comments/4fyt3v/why_doesnt_stdany_suppor=
t_move_only_types/>,=20
>>>> there are several choices being noted. I think throwing is the only=20
>>>> acceptable one.
>>>>
>>>> Doing this makes `any` effectively a move-only type.
>>>>>
>>>> No. The static type allows it to be copied, so it is not a move-only=
=20
>>>> type. The exceptional behavior at runtime is another topic.
>>>>
>>>
>>> I said "effectively". That is, it would be nearly universally used as i=
f=20
>>> it were a move-only type, with copying being a 1-in-100 feature that a =
rare=20
>>> few would dare touch due to its fragility. It would become a de-facto=
=20
>>> move-only type, even though it were technically permissible.
>>>
>>> You may as well give it a `clone` member function.
>>>
>>> Remember: one of the main use cases for `any` is for pass-through=20
>>> values. That is, you have two systems A and B. A needs to pass an objec=
t to=20
>>> B. Both A and B know what type it is. But they have to communicate by s=
ome=20
>>> intermediate system K. And we don't want to hard-code the type being=20
>>> passed, since K will be used for communication between many different=
=20
>>> objects.
>>>
>>> So the question is this: would you *ever* write K such that it would=20
>>> copy an `any`, if you knew that copying could throw an exception just=
=20
>>> because the `any` was given a non-copyable type? *Of course not.* You=
=20
>>> would go out of your way to avoid writing K such that it copied the dat=
a.=20
>>> It would take the `any` by `&&`, and it would move it into intermediate=
=20
>>> storage. And when it gave it to B, it would either pass along a `const&=
` or=20
>>> transfer ownership explicitly.
>>>
>>> This also affects the design of K. If B needs to gain ownership of the=
=20
>>> object, then K can only transfer that object *once*. Perfectly fine if =
K is=20
>>> an event system, but if it's something more complex, where it may need =
to=20
>>> call B multiple times, that becomes problematic. But at the same time,=
=20
>>> you'll find a way around it. Why?
>>>
>>> Because otherwise, you'd be writing K to be fragile, easily broken.=20
>>> After all, K has *absolutely no way* of resolving such an error. The=20
>>> only one who could resolve it is A, and K may well not copy the object=
=20
>>> until long after A is finished registering the `any` with K.
>>>
>>> So the safest course of action for implementing K is to make it avoid=
=20
>>> copying `any`. That is, if `any`'s copy constructor was so fragile that=
it=20
>>> would be guaranteed to fail for a whole slew of contained types.
>>>
>>> Whereas if you know that all `any` objects will be copyable, then the=
=20
>>> only reason to go out of your way to avoid copying it is if you were=20
>>> concerned about the stored value throwing exceptions in its copy=20
>>> constructor.
>>>
>>> No. Introducing `any` as parameter types will easily cause performance=
=20
>> regressions since it can really hold *any *copyable objects, which is=20
>> out of my control at all. (Imagine how to tell the user don't put a big=
=20
>> container in it except for the documentation? And how to evaluate if it =
is=20
>> being violated?)
>>
>
> How exactly does that cause a performance regression? The alternative to=
=20
> `any` is a `void*`. Which requires heap allocation (or keeping around a=
=20
> pointer to a stack or global object). `void*` is not a value-type, so it'=
s=20
> impossible to copy it.
>
> If you change your code from using `void*` to `any`, you would have no=20
> reason to suddenly decide to start copying `any` objects. Since that's an=
=20
> operation that wasn't available before. So in both cases, the big object=
=20
> was heap allocated and in both cases, the object was not copied.
>
> So where is the "performance regression"?
>
> You would only get a "performance regression" if you completely changed=
=20
> the nature of the code. And that would only happen if you aren't paying=
=20
> attention to what you're doing.
>
> Quite frankly, if you're not paying attention to what you're doing in C++=
,=20
> you shouldn't be using the language.
>
> You did not get the point.
It is a side effect *after replacing a concrete type with `any`*. Because=
=20
`any` allows any "copy" occurs in its copy constructor literally, it is=20
difficult to evaluate what the performance penalty it would be,=20
particularly when the contained object is provided by the client code.=20
Because `any` does not limit it at all, users may easily do things you=20
don't want, unless warned seriously (by some means not part of C++).
Is this the mistake of users? Partially, but not all. The design here is=20
essentially doubtful. Usually, you would care about copy of containers so=
=20
you should not pass the container by value. However, you seem to tend to a=
=20
similar but worse choice for `any` here. Why?
The fact is, `any` cannot be used as a passed-by-value parameter type that=
=20
easily. Such use need extraordinary care, within limited use cases. If you=
=20
don't find this, I think you're probably not paying enough attention to=20
what you're doing in C++.
=20
> So I will never use such a type without document carefully. Even for=20
>> totally statically typed function parameters there are similar problems:=
=20
>> will you take an arbitrary template type parameter `T` (rather than `T&&=
`=20
>> or `const T&`) as function parameter type of function templates in gener=
al=20
>> (except for well-known limited contexts like being an iterator or a=20
>> functor)?
>>
>
> ... I probably wouldn't take an `any` value as a parameter either; I'd=20
> either take a `const any&` or an `any&&`. What's your point?
>
> Also, I think that such "well-known limited contexts" are poor choices=20
> too. Particularly in modern times with move-only lambdas. I would hope th=
at=20
> the Ranges TS allows us to pass non-copyable functors to algorithms.
>
> I agree with this when talking about `any` as a parameter. I suspect=20
whether there are any good alternatives when an "any" object is really=20
needed.
Nevertheless, the use of being passed by value is not the killer feature of=
=20
>> `any` at first. To use it as a data member has no such problems.
>>
>
> It becomes a problem if it's a data member of a copyable type.
>
If you want the enclosing class to be copyable, either limit access of this=
=20
data member, or do not use the enclosing class as a function parameter at=
=20
all.=20
=20
> =20
>
>> And I doubt such random use of `any` being parameter type of public APIs=
=20
>> will lead to a bad design.
>>
>
> I don't know what you mean by "such random use of `any`". But I don't see=
=20
> the need to use `any` "randomly".
>
> Using `any` as parameter in public API is dangerous as said above. Unless=
=20
really needed with sufficient *explicit* reasons, it seems that being used=
=20
randomly.
=20
> `any` is a special-case type. It's a fine tool for its job, but that job=
=20
> is not something you should encounter frequently. Indeed, I would conside=
r=20
> frequent use of `any` to be a code smell, an indicator that you're using=
=20
> the wrong abstraction to solve a problem.
>
> I agree.
=20
> There could be a sum type of `any` and `unique_any` to cover both set of=
=20
>>>> use cases, but it is over-complicated.
>>>>
>>>> I don't think it cannot effectively "recover from". How to recover? It=
=20
>>>> depends on the logic of client code.
>>>>
>>>
>>> Generally speaking, if you needed a copy of something, you *needed a=20
>>> copy of it*. You had some specific need to have two objects that had=20
>>> the same data.
>>>
>>> If you can't get that, most of the time the only answer is program=20
>>> termination. At the very least, the local code performing the copy cann=
ot=20
>>> resolve the error.
>>>
>>> Yes, I can put it into a `unique_any`. But what if an `any` is needed=
=20
>> elsewhere (by some code not controlled by me)? Can `unique_ptr` with no=
=20
>> statically tagged type information be cast back to `any` without=20
>> significant cost in every cases? And if that can not be avoid, or should=
be=20
>> ignored ... then why not everyone just use `unique_any` and rename it to=
=20
>> `any`?
>>
>
> Then you have finally reached my point.
>
> `any` either should require the type to be copyable or `any` itself *shou=
ld=20
> not be copyable*. The half-measure you suggested, where `any` can be=20
> copied and throw if what it contains cannot be copied, is worse than eith=
er=20
> alternative.
>
> No. It can be carefully used as replacement as the former two types, and=
=20
the the combination of so-called `any` + `unique_any` is never able to=20
replace it totally.
It is questionable to conclude which is the worse alternative when they do=
=20
different things.
And eventually, I need three types including one type I should write by=20
myself, or I need just the one type I should write by myself. Which is=20
worse if the standard library still does not provide *all *of them?
=20
> It is absurd to deliberately avoid additional dynamic logic based on the=
=20
>> current features provided by static typing. In fact, the mainstream=20
>> implementations of `any` do have such extra dynamic dispatching based on=
=20
>> switch statement or virtual function calls. Even if I can pretend I don'=
t=20
>> need such features when providing interface, what if the client need it?=
=20
>> How do I (or the client) implement it without hack into the dirty=20
>> implementation details of the standard library? Or "any" is just designe=
d=20
>> to be not usable here literally? Then it spoils a good name, and I have =
to=20
>> invent a new wheel replacing instead of reusing and extending it.
>>
>
> Not every type can be used by every person. No type fits every need. I'm=
=20
> sure people would really like to be able to store non-copyable functors i=
n=20
> `std::function` too.
> =20
>
I know I would.
>
> But that doesn't mean that `std::function` is the type that should allow=
=20
> that.
>
> A non-copyable function is not a traditional "function" (decayed as a=20
function pointer). But the meaning of "any" diverges.
=20
> If you have a `vector<T>` and you need to make a copy of it so that you=
=20
>>> can perform some process on the copy (perhaps sorting it), and the copy=
=20
>>> fails... you're SOL. Optimization and debugging don't matter because yo=
u *can't=20
>>> do what you were trying to*. The only way to "recover" from this is to=
=20
>>> hope that whomever is above you can recover from calling you.
>>>
>>> Do you frequently catch `std::bad_alloc` in your code? While some peopl=
e=20
>>> do, most people don't. Because not being able to allocate memory repres=
ents=20
>>> a failure mode that most code simply cannot correct or recover from.
>>>
>>> That's irrelevant. To catch `std::bad_alloc` without rethrowing it agai=
n=20
>> is generally illogical because there is no way to recover it, and you=20
>> should not swallow such a serious (at least) whole-program problem. That=
=20
>> "whomever is above you can recover from calling you" is out of the progr=
am=20
>> so there is nothing to do in the code.
>>
>> On the other hand, exceptional state can be perfectly handled once the=
=20
>> client code figured out at which point it need to differentiate the need=
to=20
>> use copyable vs. noncopyable types. The "whomever is above you can recov=
er=20
>> from calling you" is the client which calls the portion of code throwing=
=20
>> such exceptions.
>>
>
> Unless that code is no longer on the stack, of course. As I pointed out, =
a=20
> common use case for `any` will be intermediate value transfer. Once the=
=20
> value is given, the code which did the wrong thing has already left the=
=20
> call stack to do whatever. It is only at transfer time when the exception=
=20
> would be thrown. By then, it's too late.
>
> I doubt other wrong use will behave similarly here. It is probably also=
=20
too late when you find you have copied too much. Even as internal API (with=
=20
less risks to be misused), it is not easily to be replaced after the=20
problem actually raised. You should have trade-off.
=20
> I don't see a lot of people catching `std::couldnt_copy` or whatever that=
=20
>>> `any` would throw for similar reasons. There just isn't a clean way to=
=20
>>> recover from it locally, and globally, the use of an `any` is more ofte=
n=20
>>> than not an implementation detail that's irrelevant to the outer scope.
>>>
>>> How is it not clean? I don't see it is not clean as other exceptions=20
>> when it *is *needed.
>>
>
> It's as clean as `future`'s destructor that does different things based=
=20
> on where the `future` came from=20
> <http://www.google.com/url?q=3Dhttp%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp=
%2Fthread%2Ffuture%2F~future&sa=3DD&sntz=3D1&usg=3DAFQjCNGa7SBiunC6EH0WfHFG=
8qvDAqqOhA>.=20
> If the `future` came from an `async` call, then the destructor can block=
=20
> until the async process is complete. If the `future` came from *anywhere=
=20
> else*, the destructor will just detach itself from the async operation.=
=20
> Why did this happen?
>
> Because the designers of `async` wanted blocking behavior if you didn't=
=20
> store the `future`. And much like you, they didn't want to introduce a ne=
w=20
> `special_future_like_object` that would statically have specific behavior=
..
>
> And in so doing, they created *chaos*.=20
> <http://www.google.com/url?q=3Dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc2=
2%2Fwg21%2Fdocs%2Fpapers%2F2013%2Fn3630.pdf&sa=3DD&sntz=3D1&usg=3DAFQjCNFgW=
bvvN0k4y8ASltFpcLe3WfwKWQ>
>
> Because they did not work out what they need at first, and then *change *
it.
=20
This is not the case here.
Having a class change its behavior in such a fundamental way, based solely=
=20
> on how it was initialized, is not a "clean" method of coding. It makes it=
=20
> very difficult to look at a piece of code and statically know if it is=20
> reasonable.
>
>
For the case of `any`, it is already not so clean. It is the half-measure=
=20
to grant false assumption about behavior of copy construction to users,=20
since the precise behavior may be not measurable at all - it can be=20
anything out of your control. Both disallowing copying totally and allowing=
=20
copying + moving are more natural.
Because it is named `any`, not `any_copyable`, it gives users extra=20
surprise.
=20
> Also, it should be noted that it wouldn't be difficult at all to create a=
=20
> template wrapper type for non-copyable types, which will have a copy=20
> constructor but will throw if you try to use it. That would give you most=
=20
> of the effect you want.
>
> You would need `make_noncopyable_any<T>` to create such an `any` (if `T`=
=20
> is copyable, it won't wrap it). And you would need=20
> `noncopyable_any_cast<T>` to cast it back (it would first try getting the=
=20
> wrapped `T`; if that failed, it would try to get `T` directly. That allow=
=20
> `T` to be copyable). Both of which can be written outside of the class.
>
> So if you really, *truly* want this... you can still do it with `any` as=
=20
> it currently stands.
>
>
Good workaround. But no, how to initialize the wrapper? What if an instance=
=20
of `std::atomic`? Why bother more indirect step to do the literally correct=
=20
thing (to initialize "any" object)?
If you think it is dangerous to allow noncopyable objects silently=20
initialize the `any` object, that's fair. You want to differentiate them.=
=20
OK. Let's have the compromise. Why should it be out of the interface of the=
=20
class `any`? Can you have a constructor template with a special tag to=20
indicate this use?
Even not, should the wrapper be standardized?
=20
*More *problems.
So the question is one of numbers. The number of people who genuinely *need=
*=20
>>>>> to copy their `any`s vs. the number of people who genuinely need to s=
tore=20
>>>>> non-copyable objects in `any`. And let's be frank: we have absolutely=
no=20
>>>>> idea of the answer to either of these questions.
>>>>>
>>>>> That's irrelevant.
>>>>
>>>
>>> Yes, it is relevant. You're asking for a change to be made to the natur=
e=20
>>> of a standard library type. Therefore, you need to justify that change.
>>>
>>> If you could show that there is a great deal of need to be able to stor=
e=20
>>> non-copyable objects in `any`, then you would have some justification f=
or=20
>>> your idea. Similarly, if we could show that the number of people who=20
>>> genuinely need to copy their `any`'s is large, then making `any`'s copy=
=20
>>> constructor fragile would hurt their ability to do what they need done.
>>>
>> Before the ballot, let's gather the consensus first. Do you think "any"=
=20
>> is the right name, without any possible misconception to new users,=20
>> *absolutely*?
>>
>
> It fits right in with C++'s uniform initialization that isn't uniform,=20
> perfect forwarding that isn't perfect, a `function` wrapper that can't wr=
ap=20
> every function, and a never-empty `variant` that can be empty.
>
> C++ is *filled* with such things. Who will notice one more?
>
> Avoid to spread certainly ill-designed things. Ask the ones who insist on=
=20
teachability to correct it, before you get it more wrong :)
And this is the library, not the core language. It is too easy to roll=20
one's own wheels too make them relatively useless. That's a bad sign.
=20
> And quite frankly, an `any` that can't hold any type is far less misnamed=
=20
> than our dynamic array class being named "vector".
>
I agree.
How ever, an "array" is even more ill-named. (With mysteries come from=20
implementation details... is it guaranteed O(1) access of element at=20
first?) Similar thing in the B language is just the "vector".
(Ouch, what about Iliffe vectors?)
A better "array" may be the concept which has some sorts of operator[].
But who cares? Almost everyone is *taught *with those misleading notions=20
for decades. Save themselves. RAmen.
However, no one was taught "any" should be copyable. That's also why=20
someone will be surprised.
> Also, do you really want to argue "possible misconception to new users"?=
=20
> Don't you think users will find it far more surprising that a type that i=
s=20
> supposedly copyable will emit an exception on copy for seemingly no reaso=
n?=20
> Not to mention that such surprises will be *runtime errors*, rather than=
=20
> compile-time failures...
>
> They should not be so surprised if they know what type erasure stands for=
..
=20
> By your own logic, either `any` as it stands or non-copyable `any` are=20
> more "ideal" than a throw-on-copy `any`.
>
> I don't think that is relevant to this point, particularly as there have=
=20
>> been people got surprised by the fact that `std::any` needs the containe=
d=20
>> type to be copyable. Whether to change `std::any` or not at last, it=20
>> currently doesn't behave ideally.
>>
>
> *C++ itself* doesn't behave ideally; why should we expect its types to do=
=20
> so?
>
Most users would easily find a flawed library interface. A few of them will=
=20
find the core language broken, but before that they may probably have the=
=20
work done. Don't trouble them. That's the life style of C++:)
=20
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/d74394a3-1b3b-414d-8df0-4fd9f1ce740e%40isocpp.or=
g.
------=_Part_5512_866302408.1461583747310
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=
=9F=E6=9C=9F=E6=97=A5 UTC+8=E4=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=
=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Saturday, April 23, 2016 at 10:36:18 AM UTC-4, FrankHB1989=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=E5=9C=A8 2=
016=E5=B9=B44=E6=9C=8823=E6=97=A5=E6=98=9F=E6=9C=9F=E5=85=AD UTC+8=E4=B8=8B=
=E5=8D=881:36:15=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<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 Friday, April 22, 2016 at 1=
0:05:37 PM UTC-4, FrankHB1989 wrote:<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"><div></div><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></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div> If this is determined by design, what is the reason? Just because=
"the standard library types are predominantly value types"? Well=
, I don't think `any` is designed for only holding "the standard l=
ibrary types".<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div>If you believe that the standard should have a `s=
hared_any`, then propose that. But `any` isn't going to change just bec=
ause you want different behavior.<br></div></div></blockquote><div><br>No, =
I won't. It can't be `shared_any`, because of the semantics. An `an=
y` object being copied is not shared with copied instance. The reason of in=
sisting non-sharing as the default behavior of copy constructor in general =
is exactly what you have said, and I have no problems with it.<br></div></d=
iv></blockquote><div><br>If you want `any` to be copyable, and you want it =
to be able to hold a non-copyable type... what happens when you copy it if =
it holds a non-copyable type? Should it throw some kind of exception?<br><b=
r></div></div></blockquote><div>From <a href=3D"https://www.reddit.com/r/cp=
p/comments/4fyt3v/why_doesnt_stdany_support_move_only_types/" rel=3D"nofoll=
ow" target=3D"_blank" onmousedown=3D"this.href=3D'https://www.google.co=
m/url?q\x3dhttps%3A%2F%2Fwww.reddit.com%2Fr%2Fcpp%2Fcomments%2F4fyt3v%2Fwhy=
_doesnt_stdany_support_move_only_types%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3=
dAFQjCNH29iXgIdTdHoQw456Sr4ymMs-S1Q';return true;" onclick=3D"this.href=
=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.reddit.com%2Fr%2F=
cpp%2Fcomments%2F4fyt3v%2Fwhy_doesnt_stdany_support_move_only_types%2F\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH29iXgIdTdHoQw456Sr4ymMs-S1Q';retur=
n true;">this discussion on reddit</a>, there are several choices being not=
ed. I think throwing is the only acceptable one.<br><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div>Doing this makes `any` eff=
ectively a move-only type.</div></div></blockquote><div>No. The static type=
allows it to be copied, so it is not a move-only type. The exceptional beh=
avior at runtime is another topic.<br></div></div></blockquote><div><br>I s=
aid "effectively". That is, it would be nearly universally used a=
s if it were a move-only type, with copying being a 1-in-100 feature that a=
rare few would dare touch due to its fragility. It would become a de-facto=
move-only type, even though it were technically permissible.<br><br>You ma=
y as well give it a `clone` member function.<br><br>Remember: one of the ma=
in use cases for `any` is for pass-through values. That is, you have two sy=
stems A and B. A needs to pass an object to B. Both A and B know what type =
it is. But they have to communicate by some intermediate system K. And we d=
on't want to hard-code the type being passed, since K will be used for =
communication between many different objects.<br><br>So the question is thi=
s: would you <i>ever</i> write K such that it would copy an `any`, if you k=
new that copying could throw an exception just because the `any` was given =
a non-copyable type? <i>Of course not.</i> You would go out of your way to =
avoid writing K such that it copied the data. It would take the `any` by `&=
amp;&`, and it would move it into intermediate storage. And when it gav=
e it to B, it would either pass along a `const&` or transfer ownership =
explicitly.<br><br>This also affects the design of K. If B needs to gain ow=
nership of the object, then K can only transfer that object *once*. Perfect=
ly fine if K is an event system, but if it's something more complex, wh=
ere it may need to call B multiple times, that becomes problematic. But at =
the same time, you'll find a way around it. Why?<br><br>Because otherwi=
se, you'd be writing K to be fragile, easily broken. After all, K has <=
i>absolutely no way</i> of resolving such an error. The only one who could =
resolve it is A, and K may well not copy the object until long after A is f=
inished registering the `any` with K.<br><br>So the safest course of action=
for implementing K is to make it avoid copying `any`. That is, if `any`=
9;s copy constructor was so fragile that it would be guaranteed to fail for=
a whole slew of contained types.<br><br>Whereas if you know that all `any`=
objects will be copyable, then the only reason to go out of your way to av=
oid copying it is if you were concerned about the stored value throwing exc=
eptions in its copy constructor.<br><br></div></div></blockquote><div>No. I=
ntroducing `any` as parameter types will easily cause performance regressio=
ns since it can really hold <i>any </i>copyable objects, which is out of my=
control at all. (Imagine how to tell the user don't put a big containe=
r in it except for the documentation? And how to evaluate if it is being vi=
olated?)</div></div></blockquote><div><br>How exactly does that cause a per=
formance regression? The alternative to `any` is a `void*`. Which requires =
heap allocation (or keeping around a pointer to a stack or global object). =
`void*` is not a value-type, so it's impossible to copy it.<br><br>If y=
ou change your code from using `void*` to `any`, you would have no reason t=
o suddenly decide to start copying `any` objects. Since that's an opera=
tion that wasn't available before. So in both cases, the big object was=
heap allocated and in both cases, the object was not copied.<br><br>So whe=
re is the "performance regression"?<br><br>You would only get a &=
quot;performance regression" if you completely changed the nature of t=
he code. And that would only happen if you aren't paying attention to w=
hat you're doing.<br><br>Quite frankly, if you're not paying attent=
ion to what you're doing in C++, you shouldn't be using the languag=
e.<br><br></div></div></blockquote><div>You did not get the point.<br><br>I=
t is a side effect <i>after replacing a concrete type with `any`</i>. Becau=
se `any` allows any "copy" occurs in its copy constructor literal=
ly, it is difficult to evaluate what the performance penalty it would be, p=
articularly when the contained object is provided by the client code. Becau=
se `any` does not limit it at all, users may easily do things you don't=
want, unless warned seriously (by some means not part of C++).<br><br>Is t=
his the mistake of users? Partially, but not all. The design here is essent=
ially doubtful. Usually, you would care about copy of containers so you sho=
uld not pass the container by value. However, you seem to tend to a similar=
but worse choice for `any` here. Why?<br><br>The fact is, `any` cannot be =
used as a passed-by-value parameter type that easily. Such use need extraor=
dinary care, within limited use cases. If you don't find this, I think =
you're probably not paying enough attention to what you're doing in=
C++.<br><br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>So I will never use such a type without document carefully. E=
ven for totally statically typed function parameters there are similar prob=
lems: will you take an arbitrary template type parameter `T` (rather than `=
T&&` or `const T&`) as function parameter type of function temp=
lates in general (except for well-known limited contexts like being an iter=
ator or a functor)?<br></div></div></blockquote><div><br>... I probably wou=
ldn't take an `any` value as a parameter either; I'd either take a =
`const any&` or an `any&&`. What's your point?<br><br>Also,=
I think that such "well-known limited contexts" are poor choices=
too. Particularly in modern times with move-only lambdas. I would hope tha=
t the Ranges TS allows us to pass non-copyable functors to algorithms.<br><=
br></div></div></blockquote><div>I agree with this when talking about `any`=
as a parameter. I suspect whether there are any good alternatives when an =
"any" object is really needed.<br><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>Nevertheless, the use of being passe=
d by value is not the killer feature of `any` at first. To use it as a data=
member has no such problems.</div></div></blockquote><div><br>It becomes a=
problem if it's a data member of a copyable type.<br></div></div></blo=
ckquote><div>If you want the enclosing class to be copyable, either limit a=
ccess of this data member, or do not use the enclosing class as a function =
parameter at all. <br></div><div>=C2=A0<br></div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div>And I doubt such random use of `any=
` being parameter type of public APIs will lead to a bad design.<br></div><=
/div></blockquote><div><br>I don't know what you mean by "such ran=
dom use of `any`". But I don't see the need to use `any` "ran=
domly".<br><br></div></div></blockquote><div>Using `any` as parameter =
in public API is dangerous as said above. Unless really needed with suffici=
ent <i>explicit</i> reasons, it seems that being used randomly.<br>=C2=A0<b=
r></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"><div>=
`any` is a special-case type. It's a fine tool for its job, but that jo=
b is not something you should encounter frequently. Indeed, I would conside=
r frequent use of `any` to be a code smell, an indicator that you're us=
ing the wrong abstraction to solve a problem.<br><br></div></div></blockquo=
te><div>I agree.<br>=C2=A0<br></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"><div></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"><div></div><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></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div></=
blockquote><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"><div>Th=
ere could be a sum type of `any` and `unique_any` to cover both set of use =
cases, but it is over-complicated.<br><br>I don't think it cannot effec=
tively "recover from". How to recover? It depends on the logic of=
client code.</div></div></blockquote><div><br>Generally speaking, if you n=
eeded a copy of something, you <i>needed a copy of it</i>. You had some spe=
cific need to have two objects that had the same data.<br><br>If you can=
9;t get that, most of the time the only answer is program termination. At t=
he very least, the local code performing the copy cannot resolve the error.=
<br><br></div></div></blockquote><div>=C2=A0Yes, I can put it into a `uniqu=
e_any`. But what if an `any` is needed elsewhere (by some code not controll=
ed by me)? Can `unique_ptr` with no statically tagged type information be c=
ast back to `any` without significant cost in every cases? And if that can =
not be avoid, or should be ignored ... then why not everyone just use `uniq=
ue_any` and rename it to `any`?<br></div></div></blockquote><div><br>Then y=
ou have finally reached my point.<br><br>`any` either should require the ty=
pe to be copyable or `any` itself=C2=A0<i></i><i>should not be copyable</i>=
.. The half-measure you suggested, where `any` can be copied and throw if wh=
at it contains cannot be copied, is worse than either alternative.<br><br><=
/div></div></blockquote><div>No. It can be carefully used as replacement as=
the former two types, and the the combination of so-called `any` + `unique=
_any` is never able to replace it totally.<br><br>It is questionable to con=
clude which is the worse alternative when they do different things.<br><br>=
And eventually, I need three types including one type I should write by mys=
elf, or I need just the one type I should write by myself. Which is worse i=
f the standard library still does not provide <i>all </i>of them?<br>=C2=A0=
<br></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"><di=
v></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>It is=
absurd to deliberately avoid additional dynamic logic based on the current=
features provided by static typing. In fact, the mainstream implementation=
s of `any` do have such extra dynamic dispatching based on switch statement=
or virtual function calls. Even if I can pretend I don't need such fea=
tures when providing interface, what if the client need it? How do I (or th=
e client) implement it without hack into the dirty implementation details o=
f the standard library? Or "any" is just designed to be not usabl=
e here literally? Then it spoils a good name, and I have to invent a new wh=
eel replacing instead of reusing and extending it.<br></div></div></blockqu=
ote><div><br>Not every type can be used by every person. No type fits every=
need. I'm sure people would really like to be able to store non-copyab=
le functors in `std::function` too.<br>=C2=A0<br></div></div></blockquote><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>I know I =
would.<br><br>But that doesn't mean that `std::function` is the type th=
at should allow that.<br><br></div></div></blockquote><div>A non-copyable f=
unction is not a traditional "function" (decayed as a function po=
inter). But the meaning of "any" diverges.<br>=C2=A0<br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></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"><div>If you have a `vector<=
T>` and you need to make a copy of it so that you can perform some proce=
ss on the copy (perhaps sorting it), and the copy fails... you're SOL. =
Optimization and debugging don't matter because you <i>can't do wha=
t you were trying to</i>. The only way to "recover" from this is =
to hope that whomever is above you can recover from calling you.<br><br>Do =
you frequently catch `std::bad_alloc` in your code? While some people do, m=
ost people don't. Because not being able to allocate memory represents =
a failure mode that most code simply cannot correct or recover from.<br><br=
></div></div></blockquote><div>That's irrelevant. To catch `std::bad_al=
loc` without rethrowing it again is generally illogical because there is no=
way to recover it, and you should not swallow such a serious (at least) wh=
ole-program problem. That "whomever is above you can recover from call=
ing you" is out of the program so there is nothing to do in the code.<=
br><br>On the other hand, exceptional state can be perfectly handled once t=
he client code figured out at which point it need to differentiate the need=
to use copyable vs. noncopyable types. The "whomever is above you can=
recover from calling you" is the client which calls the portion of co=
de throwing such exceptions.<br></div></div></blockquote><div><br>Unless th=
at code is no longer on the stack, of course. As I pointed out, a common us=
e case for `any` will be intermediate value transfer. Once the value is giv=
en, the code which did the wrong thing has already left the call stack to d=
o whatever. It is only at transfer time when the exception would be thrown.=
By then, it's too late.<br><br></div></div></blockquote><div>I doubt o=
ther wrong use will behave similarly here. It is probably also too late whe=
n you find you have copied too much. Even as internal API (with less risks =
to be misused), it is not easily to be replaced after the problem actually =
raised. You should have trade-off.<br>=C2=A0<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div>I don't see a lot of people catching `s=
td::couldnt_copy` or whatever that `any` would throw for similar reasons. T=
here just isn't a clean way to recover from it locally, and globally, t=
he use of an `any` is more often than not an implementation detail that'=
;s irrelevant to the outer scope.<br><br></div></div></blockquote><div>How =
is it not clean? I don't see it is not clean as other exceptions when i=
t <i>is </i>needed.<br></div></div></blockquote><div><br>It's as clean =
as `future`'s destructor that <a href=3D"http://www.google.com/url?q=3D=
http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fthread%2Ffuture%2F~future&=
sa=3DD&sntz=3D1&usg=3DAFQjCNGa7SBiunC6EH0WfHFG8qvDAqqOhA" target=3D=
"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google=
..com/url?q\x3dhttp%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fthread%2Ffuture%=
2F~future\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGa7SBiunC6EH0WfHFG8qvDAqq=
OhA';return true;" onclick=3D"this.href=3D'http://www.google.com/ur=
l?q\x3dhttp%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fthread%2Ffuture%2F~futu=
re\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGa7SBiunC6EH0WfHFG8qvDAqqOhA'=
;;return true;">does different things based on where the `future` came from=
</a>. If the `future` came from an `async` call, then the destructor can bl=
ock until the async process is complete. If the `future` came from <i>anywh=
ere else</i>, the destructor will just detach itself from the async operati=
on. Why did this happen?<br><br>Because the designers of `async` wanted blo=
cking behavior if you didn't store the `future`. And much like you, the=
y didn't want to introduce a new `special_future_like_object` that woul=
d statically have specific behavior.<br><br>And in so doing, <a href=3D"htt=
p://www.google.com/url?q=3Dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg=
21%2Fdocs%2Fpapers%2F2013%2Fn3630.pdf&sa=3DD&sntz=3D1&usg=3DAFQ=
jCNFgWbvvN0k4y8ASltFpcLe3WfwKWQ" target=3D"_blank" rel=3D"nofollow" onmouse=
down=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.op=
en-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2013%2Fn3630.pdf\x26sa\x3=
dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgWbvvN0k4y8ASltFpcLe3WfwKWQ';return tr=
ue;" onclick=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%=
2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2013%2Fn3630.pdf\=
x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFgWbvvN0k4y8ASltFpcLe3WfwKWQ';r=
eturn true;">they created <i>chaos</i>.</a><br><br></div></div></blockquote=
><div>Because they did not work out what they need at first, and then <i>ch=
ange </i>it.<br>=C2=A0<br>This is not the case here.<br><br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Having a class ch=
ange its behavior in such a fundamental way, based solely on how it was ini=
tialized, is not a "clean" method of coding. It makes it very dif=
ficult to look at a piece of code and statically know if it is reasonable.<=
br><br></div></div></blockquote><div><br>For the case of `any`, it is alrea=
dy not so clean. It is the half-measure to grant false assumption about beh=
avior of copy construction to users, since the precise behavior may be not =
measurable at all - it can be anything out of your control. Both disallowin=
g copying totally and allowing copying + moving are more natural.<br><br>Be=
cause it is named `any`, not `any_copyable`, it gives users extra surprise.=
<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>Also, it should be noted that it wouldn't be difficult at=
all to create a template wrapper type for non-copyable types, which will h=
ave a copy constructor but will throw if you try to use it. That would give=
you most of the effect you want.<br><br>You would need `make_noncopyable_a=
ny<T>` to create such an `any` (if `T` is copyable, it won't wrap=
it). And you would need `noncopyable_any_cast<T>` to cast it back (i=
t would first try getting the wrapped `T`; if that failed, it would try to =
get `T` directly. That allow `T` to be copyable). Both of which can be writ=
ten outside of the class.<br><br>So if you really, <i>truly</i> want this..=
.. you can still do it with `any` as it currently stands.<br></div><div><br>=
</div></div></blockquote><div><br>Good workaround. But no, how to initializ=
e the wrapper? What if an instance of `std::atomic`? Why bother more indire=
ct step to do the literally correct thing (to initialize "any" ob=
ject)?<br><br>If you think it is dangerous to allow noncopyable objects sil=
ently initialize the `any` object, that's fair. You want to differentia=
te them. OK. Let's have the compromise. Why should it be out of the int=
erface of the class `any`? Can you have a constructor template with a speci=
al tag to indicate this use?<br><br>Even not, should the wrapper be standar=
dized?<br>=C2=A0<br><i>More </i>problems.<br><br></div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><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"><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"ltr">=
<div></div><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>So the question is one of numbers. The number of people who genuin=
ely <i>need</i> to copy their `any`s vs. the number of people who genuinely=
need to store non-copyable objects in `any`. And let's be frank: we ha=
ve absolutely no idea of the answer to either of these questions.<br><br></=
div></div></blockquote><div>That's irrelevant.</div></div></blockquote>=
<div><br>Yes, it is relevant. You're asking for a change to be made to =
the nature of a standard library type. Therefore, you need to justify that =
change.<br><br>If you could show that there is a great deal of need to be a=
ble to store non-copyable objects in `any`, then you would have some justif=
ication for your idea. Similarly, if we could show that the number of peopl=
e who genuinely need to copy their `any`'s is large, then making `any`&=
#39;s copy constructor fragile would hurt their ability to do what they nee=
d done.<br></div></div></blockquote><div>Before the ballot, let's gathe=
r the consensus first. Do you think "any" is the right name, with=
out any possible misconception to new users, <i>absolutely</i>?<br></div></=
div></blockquote><div><br>It fits right in with C++'s uniform initializ=
ation that isn't uniform, perfect forwarding that isn't perfect, a =
`function` wrapper that can't wrap every function, and a never-empty `v=
ariant` that can be empty.<br><br>C++ is <i>filled</i> with such things. Wh=
o will notice one more?<br><br></div></div></blockquote><div>Avoid to sprea=
d certainly ill-designed things. Ask the ones who insist on teachability to=
correct it, before you get it more wrong :)<br><br>And this is the library=
, not the core language. It is too easy to roll one's own wheels too ma=
ke them relatively useless. That's a bad sign.<br>=C2=A0<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>And quite fra=
nkly, an `any` that can't hold any type is far less misnamed than our d=
ynamic array class being named "vector".<br></div></div></blockqu=
ote><div><br>I agree.<br><br>How ever, an "array" is even more il=
l-named. (With mysteries come from implementation details... is it guarante=
ed O(1) access of element at first?) Similar thing in the B language is jus=
t the "vector".<br><br> (Ouch, what about Iliffe vectors?)<br><br=
>A better "array" may be the concept which has some sorts of oper=
ator[].<br><br>But who cares? Almost everyone is <i>taught </i>with those m=
isleading notions for decades. Save themselves. RAmen.<br><br>However, no o=
ne was taught "any" should be copyable. That's also why someo=
ne will be surprised.<br><br></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"><div><br>Also, do you really want to argue "pos=
sible misconception to new users"? Don't you think users will find=
it far more surprising that a type that is supposedly copyable will emit a=
n exception on copy for seemingly no reason? Not to mention that such surpr=
ises will be <i>runtime errors</i>, rather than compile-time failures...<br=
><br></div></div></blockquote><div>They should not be so surprised if they =
know what type erasure stands for.<br>=C2=A0<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div>By your own logic, either `an=
y` as it stands or non-copyable `any` are more "ideal" than a thr=
ow-on-copy `any`.<br><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div>I don't think that is relevant to this point, particu=
larly as there have been people got surprised by the fact that `std::any` n=
eeds the contained type to be copyable. Whether to change `std::any` or not=
at last, it currently doesn't behave ideally.<br></div></div></blockqu=
ote><div><br><i>C++ itself</i> doesn't behave ideally; why should we ex=
pect its types to do so?<br></div></div></blockquote><div>Most users would =
easily find a flawed library interface. A few of them will find the core la=
nguage broken, but before that they may probably have the work done. Don=
9;t trouble them. That's the life style of C++:)<br><br>=C2=A0<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/d74394a3-1b3b-414d-8df0-4fd9f1ce740e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d74394a3-1b3b-414d-8df0-4fd9f1ce740e=
%40isocpp.org</a>.<br />
------=_Part_5512_866302408.1461583747310--
------=_Part_5511_669475143.1461583747309--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 Apr 2016 11:11:59 -0700 (PDT)
Raw View
------=_Part_2490_1890767912.1461694320083
Content-Type: multipart/alternative;
boundary="----=_Part_2491_1292977661.1461694320084"
------=_Part_2491_1292977661.1461694320084
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, April 25, 2016 at 7:29:07 AM UTC-4, FrankHB1989 wrote:
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5 U=
TC+8=E4=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>> How exactly does that cause a performance regression? The alternative to=
=20
>> `any` is a `void*`. Which requires heap allocation (or keeping around a=
=20
>> pointer to a stack or global object). `void*` is not a value-type, so it=
's=20
>> impossible to copy it.
>>
>> If you change your code from using `void*` to `any`, you would have no=
=20
>> reason to suddenly decide to start copying `any` objects. Since that's a=
n=20
>> operation that wasn't available before. So in both cases, the big object=
=20
>> was heap allocated and in both cases, the object was not copied.
>>
>> So where is the "performance regression"?
>>
>> You would only get a "performance regression" if you completely changed=
=20
>> the nature of the code. And that would only happen if you aren't paying=
=20
>> attention to what you're doing.
>>
>> Quite frankly, if you're not paying attention to what you're doing in=20
>> C++, you shouldn't be using the language.
>>
>> You did not get the point.
>
> It is a side effect *after replacing a concrete type with `any`*.
>
Stop. Why would you ever be doing that?
`any` is a type-safe replacement for `void*`, not "a concrete type". So=20
what is your code doing where you uses to take a specific type, and now you=
=20
have decided to take anything? Especially when you were presumably taking=
=20
that type as a by-value parameter (more on that later).
It seems to me that the type you would be interested in is `variant`.
Because `any` allows any "copy" occurs in its copy constructor literally,=
=20
> it is difficult to evaluate what the performance penalty it would be,=20
> particularly when the contained object is provided by the client code.=20
> Because `any` does not limit it at all, users may easily do things you=20
> don't want, unless warned seriously (by some means not part of C++).
>
.... maybe you haven't gotten the point yet, but *I don't care*.
The fact that someone, somewhere, can misuse something to their performance=
=20
detriment is not by itself sufficient reason to disallow it. `unique_ptr`=
=20
disallows copying because it conceptually makes no sense to copy something=
=20
which is uniquely owned by this object. It's a logical contradiction and=20
therefore disallowed.
That's not the case with `any`.
Is this the mistake of users? Partially, but not all. The design here is=20
> essentially doubtful. Usually, you would care about copy of containers so=
=20
> you should not pass the container by value. However, you seem to tend to =
a=20
> similar but worse choice for `any` here. Why?
>
> The fact is, `any` cannot be used as a passed-by-value parameter type tha=
t=20
> easily.
>
So what? Why are you so focused on using `any` as a "by-value parameter"?=
=20
Nobody is suggesting that people should start writing APIs that take `any`=
=20
instances as "by-value parameters". You are complaining about people doing=
=20
something that nobody actually wants to do.
Well, nobody except maybe you.
Do we tell people to take `vector` by value parameter? `optional`?=20
`variant`? `std::function`? No. We generally tell people to take such types=
=20
by reference.
=20
> Such use need extraordinary care, within limited use cases.
>
Using a `const any&` is not "extraordinary care". Nor does it limit use=20
cases.
=20
> Nevertheless, the use of being passed by value is not the killer feature=
=20
>>> of `any` at first. To use it as a data member has no such problems.
>>>
>>
>> It becomes a problem if it's a data member of a copyable type.
>>
> If you want the enclosing class to be copyable, either limit access of=20
> this data member, or do not use the enclosing class as a function paramet=
er=20
> at all.
>
Again with the "function parameter" stuff. You act like being a by-value=20
parameter is the end-all-be-all of types.
It isn't.
Whether a type is copyable or not has *nothing* to do with whether you=20
should use it as a by-value parameter or not. `vector` is copyable, but=20
that doesn't mean you should copy it a lot.
=20
> Not every type can be used by every person. No type fits every need. I'm=
=20
>> sure people would really like to be able to store non-copyable functors =
in=20
>> `std::function` too.
>> =20
>>
> I know I would.
>>
>> But that doesn't mean that `std::function` is the type that should allow=
=20
>> that.
>>
>> A non-copyable function is not a traditional "function" (decayed as a=20
> function pointer). But the meaning of "any" diverges.
>
Yes, `any` diverges from `void*`. That's because `any` is designed to be a=
=20
*safe* `void*`. It achieves this in two ways:
1. Casting is type-checked and will fail if the user does not supply the=20
actual type used to create the `any`.
2. The value stored is *owned* by the `any`, thus preventing any chance of=
=20
the object no longer being valid by the time it is recovered.
If you want to believe that people will expect `any` to provide #1 without=
=20
#2, go ahead.
=20
> Having a class change its behavior in such a fundamental way, based solel=
y=20
>> on how it was initialized, is not a "clean" method of coding. It makes i=
t=20
>> very difficult to look at a piece of code and statically know if it is=
=20
>> reasonable.
>>
>>
> For the case of `any`, it is already not so clean. It is the half-measure=
=20
> to grant false assumption about behavior of copy construction to users,=
=20
> since the precise behavior may be not measurable at all - it can be=20
> anything out of your control. Both disallowing copying totally and allowi=
ng=20
> copying + moving are more natural.
>
> Because it is named `any`, not `any_copyable`, it gives users extra=20
> surprise.
>
That assumes the user would expect `any` (or any C++ type) to not be=20
copyable. I fail to see how that's a valid assumption, considering that=20
most C++ standard library types are copyable.
=20
>
>> Also, it should be noted that it wouldn't be difficult at all to create =
a=20
>> template wrapper type for non-copyable types, which will have a copy=20
>> constructor but will throw if you try to use it. That would give you mos=
t=20
>> of the effect you want.
>>
>> You would need `make_noncopyable_any<T>` to create such an `any` (if `T`=
=20
>> is copyable, it won't wrap it). And you would need=20
>> `noncopyable_any_cast<T>` to cast it back (it would first try getting th=
e=20
>> wrapped `T`; if that failed, it would try to get `T` directly. That allo=
w=20
>> `T` to be copyable). Both of which can be written outside of the class.
>>
>> So if you really, *truly* want this... you can still do it with `any` as=
=20
>> it currently stands.
>>
>>
> Good workaround. But no, how to initialize the wrapper?
>
Um... exactly like I said: `make_noncopyable_any`. This ain't rocket=20
science here.
What if an instance of `std::atomic`?
>
`any` can copy from a value or move from it. But it cannot take a value=20
from a list of arguments and a type. You would need explicit emplacement=20
construction support to do that, something like what P0032 proposes.
But if you had that, then `make_noncopyable_any` would be able to work with=
=20
immobile types too. There's nothing in the wrapper that would prevent that.
Why bother more indirect step to do the literally correct thing (to=20
> initialize "any" object)?
>
What you want is not "the literally correct thing" *just because you=20
declare it so*.
=20
> If you think it is dangerous to allow noncopyable objects silently=20
> initialize the `any` object, that's fair. You want to differentiate them.=
=20
> OK. Let's have the compromise. Why should it be out of the interface of t=
he=20
> class `any`? Can you have a constructor template with a special tag to=20
> indicate this use?
>
That's not a "compromise"; that's *surrender*.
A "compromise" is where you get some of what you want, and I get some of=20
what I want. By putting the wrapper directly into the interface of `any`,=
=20
you get *everything* you want, and I get *nothing* I want.
Remember: by creating this wrapped `any` instance, you're introducing=20
*fragility* into your codebase. It should be clear and obvious when you do=
=20
this, and it should not look like normal creation of an `any` instance. It=
=20
should *not happen by accident*.
What I suggested is a compromise. My position is that nobody should be able=
=20
to create an `any` instance which will always throw on copy. Your position=
=20
is that `any` should be able to accept non-copyable or immobile types. The=
=20
compromise is that, by default you can't use non-copyable types. But you=20
can use a wrapper to use non-copyable types, and there's nothing I can do=
=20
to stop you.
=20
> Even not, should the wrapper be standardized?
>
Probably not. There would be some advantage to it; it would be more=20
searchable, since everyone would not have different implementations. But=20
putting it in the standard also makes people think that using them is a=20
good idea.
However, no one was taught "any" should be copyable.=20
>
You mean besides everyone who has used `boost::any` for over a decade?
=20
> That's also why someone will be surprised.
>
I don't care.
Also, do you really want to argue "possible misconception to new users"?=20
>> Don't you think users will find it far more surprising that a type that =
is=20
>> supposedly copyable will emit an exception on copy for seemingly no reas=
on?=20
>> Not to mention that such surprises will be *runtime errors*, rather than=
=20
>> compile-time failures...
>>
>> They should not be so surprised if they know what type erasure stands fo=
r.
>
.... what? The concept of type erasure has nothing at all to do with the=20
behavior of a value type or reference type. You can make a type-erased=20
copyable value type (aka: `any`). You can make a type-erased moveable value=
=20
type (`unique_any`). You can make a type-erased non-owning reference type.=
=20
You can make a type-erased owning reference type (`shared_any`). And so=20
forth.
The concept of type erasure does not in any way conflict with the concept=
=20
of copying. So knowing about type erasure does not in any way require you=
=20
to believe that a type-erased type would not be copyable. Again, see=20
`std::function`.
--=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/80d79d38-58e6-426c-8897-bbedb7f34e3b%40isocpp.or=
g.
------=_Part_2491_1292977661.1461694320084
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, April 25, 2016 at 7:29:07 AM UTC-4, FrankHB1989=
wrote:<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">=E5=9C=
=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5 UTC+8=E4=
=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>How exactly does t=
hat cause a performance regression? The alternative to `any` is a `void*`. =
Which requires heap allocation (or keeping around a pointer to a stack or g=
lobal object). `void*` is not a value-type, so it's impossible to copy =
it.<br><br>If you change your code from using `void*` to `any`, you would h=
ave no reason to suddenly decide to start copying `any` objects. Since that=
's an operation that wasn't available before. So in both cases, the=
big object was heap allocated and in both cases, the object was not copied=
..<br><br>So where is the "performance regression"?<br><br>You wou=
ld only get a "performance regression" if you completely changed =
the nature of the code. And that would only happen if you aren't paying=
attention to what you're doing.<br><br>Quite frankly, if you're no=
t paying attention to what you're doing in C++, you shouldn't be us=
ing the language.<br><br></div></div></blockquote><div>You did not get the =
point.<br><br>It is a side effect <i>after replacing a concrete type with `=
any`</i>.</div></div></blockquote><div><br>Stop. Why would you ever be doin=
g that?<br><br>`any` is a type-safe replacement for `void*`, not "a co=
ncrete type". So what is your code doing where you uses to take a spec=
ific type, and now you have decided to take anything? Especially when you w=
ere presumably taking that type as a by-value parameter (more on that later=
).<br><br>It seems to me that the type you would be interested in is `varia=
nt`.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div>Because `any` allows any "copy" occurs in its copy cons=
tructor literally, it is difficult to evaluate what the performance penalty=
it would be, particularly when the contained object is provided by the cli=
ent code. Because `any` does not limit it at all, users may easily do thing=
s you don't want, unless warned seriously (by some means not part of C+=
+).<br></div></div></blockquote><div><br>... maybe you haven't gotten t=
he point yet, but <i>I don't care</i>.<br><br>The fact that someone, so=
mewhere, can misuse something to their performance detriment is not by itse=
lf sufficient reason to disallow it. `unique_ptr` disallows copying because=
it conceptually makes no sense to copy something which is uniquely owned b=
y this object. It's a logical contradiction and therefore disallowed.<b=
r><br>That's not the case with `any`.<br><br></div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div>Is this the mistake of users=
? Partially, but not all. The design here is essentially doubtful. Usually,=
you would care about copy of containers so you should not pass the contain=
er by value. However, you seem to tend to a similar but worse choice for `a=
ny` here. Why?<br><br>The fact is, `any` cannot be used as a passed-by-valu=
e parameter type that easily.</div></div></blockquote><div><br>So what? Why=
are you so focused on using `any` as a "by-value parameter"? Nob=
ody is suggesting that people should start writing APIs that take `any` ins=
tances as "by-value parameters". You are complaining about people=
doing something that nobody actually wants to do.<br><br>Well, nobody exce=
pt maybe you.<br><br>Do we tell people to take `vector` by value parameter?=
`optional`? `variant`? `std::function`? No. We generally tell people to ta=
ke such types by reference.<br>=C2=A0</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"><div> Such use need extraordinary care, with=
in limited use cases.</div></div></blockquote><div><br>Using a `const any&a=
mp;` is not "extraordinary care". Nor does it limit use cases.<br=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div></div></blockquote><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"><div></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>Nevertheless, the use of being=
passed by value is not the killer feature of `any` at first. To use it as =
a data member has no such problems.</div></div></blockquote><div><br>It bec=
omes a problem if it's a data member of a copyable type.<br></div></div=
></blockquote><div>If you want the enclosing class to be copyable, either l=
imit access of this data member, or do not use the enclosing class as a fun=
ction parameter at all.<br></div></div></blockquote><div><br>Again with the=
"function parameter" stuff. You act like being a by-value parame=
ter is the end-all-be-all of types.<br><br>It isn't.<br><br>Whether a t=
ype is copyable or not has <i>nothing</i> to do with whether you should use=
it as a by-value parameter or not. `vector` is copyable, but that doesn=
9;t mean you should copy it a lot.<br>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"ltr"><div></div><div></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div></div></div></blockquote><div>Not ev=
ery type can be used by every person. No type fits every need. I'm sure=
people would really like to be able to store non-copyable functors in `std=
::function` too.<br>=C2=A0<br></div></div></blockquote><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>I know I would.<br><br>But that d=
oesn't mean that `std::function` is the type that should allow that.<br=
><br></div></div></blockquote><div>A non-copyable function is not a traditi=
onal "function" (decayed as a function pointer). But the meaning =
of "any" diverges.<br></div></div></blockquote><div><br>Yes, `any=
` diverges from `void*`. That's because `any` is designed to be a <i>sa=
fe</i> `void*`. It achieves this in two ways:<br><br>1. Casting is type-che=
cked and will fail if the user does not supply the actual type used to crea=
te the `any`.<br><br>2. The value stored is <i>owned</i> by the `any`, thus=
preventing any chance of the object no longer being valid by the time it i=
s recovered.<br><br>If you want to believe that people will expect `any` to=
provide #1 without #2, go ahead.<br>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div></div></blockquote></div></blockquote><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div>Having a class change its behavior in su=
ch a fundamental way, based solely on how it was initialized, is not a &quo=
t;clean" method of coding. It makes it very difficult to look at a pie=
ce of code and statically know if it is reasonable.<br><br></div></div></bl=
ockquote><div><br>For the case of `any`, it is already not so clean. It is =
the half-measure to grant false assumption about behavior of copy construct=
ion to users, since the precise behavior may be not measurable at all - it =
can be anything out of your control. Both disallowing copying totally and a=
llowing copying + moving are more natural.<br><br>Because it is named `any`=
, not `any_copyable`, it gives users extra surprise.<br></div></div></block=
quote><div><br>That assumes the user would expect `any` (or any C++ type) t=
o not be copyable. I fail to see how that's a valid assumption, conside=
ring that most C++ standard library types are copyable.<br><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>=C2=A0<br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Also, it sh=
ould be noted that it wouldn't be difficult at all to create a template=
wrapper type for non-copyable types, which will have a copy constructor bu=
t will throw if you try to use it. That would give you most of the effect y=
ou want.<br><br>You would need `make_noncopyable_any<T>` to create su=
ch an `any` (if `T` is copyable, it won't wrap it). And you would need =
`noncopyable_any_cast<T>` to cast it back (it would first try getting=
the wrapped `T`; if that failed, it would try to get `T` directly. That al=
low `T` to be copyable). Both of which can be written outside of the class.=
<br><br>So if you really, <i>truly</i> want this... you can still do it wit=
h `any` as it currently stands.<br></div><div><br></div></div></blockquote>=
<div><br>Good workaround. But no, how to initialize the wrapper?</div></div=
></blockquote><div><br>Um... exactly like I said: `make_noncopyable_any`. T=
his ain't rocket science here.<br></div><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> What if an instance of =
`std::atomic`?</div></div></blockquote><div><br>`any` can copy from a value=
or move from it. But it cannot take a value from a list of arguments and a=
type. You would need explicit emplacement construction support to do that,=
something like what P0032 proposes.<br><br>But if you had that, then `make=
_noncopyable_any` would be able to work with immobile types too. There'=
s nothing in the wrapper that would prevent that.<br><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Why bother more indi=
rect step to do the literally correct thing (to initialize "any" =
object)?<br></div></div></blockquote><div><br>What you want is not "th=
e literally correct thing" <i>just because you declare it so</i>.<br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div>If you think it is dangerous to allow noncopyable objects silently init=
ialize the `any` object, that's fair. You want to differentiate them. O=
K. Let's have the compromise. Why should it be out of the interface of =
the class `any`? Can you have a constructor template with a special tag to =
indicate this use?</div></div></blockquote><div><br>That's not a "=
compromise"; that's <i>surrender</i>.<br><br>A "compromise&qu=
ot; is where you get some of what you want, and I get some of what I want. =
By putting the wrapper directly into the interface of `any`, you get <i>eve=
rything</i> you want, and I get <i>nothing</i> I want.<br><br>Remember: by =
creating this wrapped `any` instance, you're introducing <i>fragility</=
i> into your codebase. It should be clear and obvious when you do this, and=
it should not look like normal creation of an `any` instance. It should <i=
>not happen by accident</i>.<br><br>What I suggested is a compromise. My po=
sition is that nobody should be able to create an `any` instance which will=
always throw on copy. Your position is that `any` should be able to accept=
non-copyable or immobile types. The compromise is that, by default you can=
't use non-copyable types. But you can use a wrapper to use non-copyabl=
e types, and there's nothing I can do to stop you.<br>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Even not, sho=
uld the wrapper be standardized?<br></div></div></blockquote><div><br>Proba=
bly not. There would be some advantage to it; it would be more searchable, =
since everyone would not have different implementations. But putting it in =
the standard also makes people think that using them is a good idea.<br><br=
></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"><div>H=
owever, no one was taught "any" should be copyable. <br></div></d=
iv></blockquote><div><br>You mean besides everyone who has used `boost::any=
` for over a decade?<br>=C2=A0</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"><div> That's also why someone will be surprised.=
<br></div></div></blockquote><div><br>I don't care.<br><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Also, do you really w=
ant to argue "possible misconception to new users"? Don't you=
think users will find it far more surprising that a type that is supposedl=
y copyable will emit an exception on copy for seemingly no reason? Not to m=
ention that such surprises will be <i>runtime errors</i>, rather than compi=
le-time failures...<br><br></div></div></blockquote><div>They should not be=
so surprised if they know what type erasure stands for.<br></div></div></b=
lockquote><div><br>... what? The concept of type erasure has nothing at all=
to do with the behavior of a value type or reference type. You can make a =
type-erased copyable value type (aka: `any`). You can make a type-erased mo=
veable value type (`unique_any`). You can make a type-erased non-owning ref=
erence type. You can make a type-erased owning reference type (`shared_any`=
). And so forth.<br><br>The concept of type erasure does not in any way con=
flict with the concept of copying. So knowing about type erasure does not i=
n any way require you to believe that a type-erased type would not be copya=
ble. Again, see `std::function`.</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/80d79d38-58e6-426c-8897-bbedb7f34e3b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/80d79d38-58e6-426c-8897-bbedb7f34e3b=
%40isocpp.org</a>.<br />
------=_Part_2491_1292977661.1461694320084--
------=_Part_2490_1890767912.1461694320083--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Thu, 28 Apr 2016 03:29:52 -0700 (PDT)
Raw View
------=_Part_8189_1281704516.1461839392903
Content-Type: multipart/alternative;
boundary="----=_Part_8190_2130209821.1461839392904"
------=_Part_8190_2130209821.1461839392904
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8827=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC=
+8=E4=B8=8A=E5=8D=882:12:00=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A
>
> On Monday, April 25, 2016 at 7:29:07 AM UTC-4, FrankHB1989 wrote:
>>
>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5 =
UTC+8=E4=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>>
>>> How exactly does that cause a performance regression? The alternative t=
o=20
>>> `any` is a `void*`. Which requires heap allocation (or keeping around a=
=20
>>> pointer to a stack or global object). `void*` is not a value-type, so i=
t's=20
>>> impossible to copy it.
>>>
>>> If you change your code from using `void*` to `any`, you would have no=
=20
>>> reason to suddenly decide to start copying `any` objects. Since that's =
an=20
>>> operation that wasn't available before. So in both cases, the big objec=
t=20
>>> was heap allocated and in both cases, the object was not copied.
>>>
>>> So where is the "performance regression"?
>>>
>>> You would only get a "performance regression" if you completely changed=
=20
>>> the nature of the code. And that would only happen if you aren't paying=
=20
>>> attention to what you're doing.
>>>
>>> Quite frankly, if you're not paying attention to what you're doing in=
=20
>>> C++, you shouldn't be using the language.
>>>
>>> You did not get the point.
>>
>> It is a side effect *after replacing a concrete type with `any`*.
>>
>
> Stop. Why would you ever be doing that?
>
The similar reason to turning a concrete type to `void*`.=20
>
> `any` is a type-safe replacement for `void*`, not "a concrete type". So=
=20
> what is your code doing where you uses to take a specific type, and now y=
ou=20
> have decided to take anything? Especially when you were presumably taking=
=20
> that type as a by-value parameter (more on that later).
>
> But `void*` does not have the problem.
It seems to me that the type you would be interested in is `variant`.
>
> Yes I also need it, but it's elsewhere. I clearly know they are different=
..
And actually I need `any` does not only to replace `void*`. An object can=
=20
have side effect in its destruction in a polymorphic way, which is not=20
possible for `void*`.
Because `any` allows any "copy" occurs in its copy constructor literally,=
=20
>> it is difficult to evaluate what the performance penalty it would be,=20
>> particularly when the contained object is provided by the client code.=
=20
>> Because `any` does not limit it at all, users may easily do things you=
=20
>> don't want, unless warned seriously (by some means not part of C++).
>>
>
> ... maybe you haven't gotten the point yet, but *I don't care*.
>
> Whether you care or not, that problem may likely occur. I'm still not sur=
e=20
how your point can work around it.
My point here is that `any` does not fit for the work very well. If you are=
=20
forced to use `any` in such a manner without control, something has already=
=20
gone wrong. And you have to ignore this problem, if you insist on using=20
`any` here anyway.
=20
> The fact that someone, somewhere, can misuse something to their=20
> performance detriment is not by itself sufficient reason to disallow it.=
=20
> `unique_ptr` disallows copying because it conceptually makes no sense to=
=20
> copy something which is uniquely owned by this object. It's a logical=20
> contradiction and therefore disallowed.
>
> That's not the case with `any`.
>
> Yes. Allowing copy is the nature of `any` (at least in the current=20
design). But this does not mean it is *suitable *to be copied in general.
=20
> Is this the mistake of users? Partially, but not all. The design here is=
=20
>> essentially doubtful. Usually, you would care about copy of containers s=
o=20
>> you should not pass the container by value. However, you seem to tend to=
a=20
>> similar but worse choice for `any` here. Why?
>>
>> The fact is, `any` cannot be used as a passed-by-value parameter type=20
>> that easily.
>>
>
> So what? Why are you so focused on using `any` as a "by-value parameter"?=
=20
> Nobody is suggesting that people should start writing APIs that take `any=
`=20
> instances as "by-value parameters". You are complaining about people doin=
g=20
> something that nobody actually wants to do.
>
> Well, nobody except maybe you.
>
> Huh? Then what you were arguing about? If you don't use `any` by-value,=
=20
when will you copy it (frequently)?
=20
> Do we tell people to take `vector` by value parameter? `optional`?=20
> `variant`? `std::function`? No. We generally tell people to take such typ=
es=20
> by reference.
>
By taking reference, object of `any` is not copied.=20
> =20
>
>> Such use need extraordinary care, within limited use cases.
>>
>
> Using a `const any&` is not "extraordinary care". Nor does it limit use=
=20
> cases.
> =20
>
Sure. That was about `any` passed by-value.
=20
> Nevertheless, the use of being passed by value is not the killer feature=
=20
>>>> of `any` at first. To use it as a data member has no such problems.
>>>>
>>>
>>> It becomes a problem if it's a data member of a copyable type.
>>>
>> If you want the enclosing class to be copyable, either limit access of=
=20
>> this data member, or do not use the enclosing class as a function parame=
ter=20
>> at all.
>>
>
> Again with the "function parameter" stuff. You act like being a by-value=
=20
> parameter is the end-all-be-all of types.
>
> It isn't.
>
> So why are you so interested in limiting the uniform behavior of copying?=
=20
If it is not used at implicit copy-initialization (mainly passing-by-value=
=20
cases), is it still error-prone?
=20
> Whether a type is copyable or not has *nothing* to do with whether you=20
> should use it as a by-value parameter or not. `vector` is copyable, but=
=20
> that doesn't mean you should copy it a lot.
>
I have already mentioned this.
If you agree that is comparable, why not force element of `vector`=20
copyable? Just because the *implementation details* of type erasure need it=
=20
to live or die in the whole type level for `any` while not for `vector`?
=20
>
>> Not every type can be used by every person. No type fits every need. I'm=
=20
>>> sure people would really like to be able to store non-copyable functors=
in=20
>>> `std::function` too.
>>> =20
>>>
>> I know I would.
>>>
>>> But that doesn't mean that `std::function` is the type that should allo=
w=20
>>> that.
>>>
>>> A non-copyable function is not a traditional "function" (decayed as a=
=20
>> function pointer). But the meaning of "any" diverges.
>>
>
> Yes, `any` diverges from `void*`. That's because `any` is designed to be =
a=20
> *safe* `void*`. It achieves this in two ways:
>
> 1. Casting is type-checked and will fail if the user does not supply the=
=20
> actual type used to create the `any`.
>
> 2. The value stored is *owned* by the `any`, thus preventing any chance=
=20
> of the object no longer being valid by the time it is recovered.
>
> If you want to believe that people will expect `any` to provide #1 withou=
t=20
> #2, go ahead.
> =20
>
True. But is this relevant to being copyable?
=20
> Having a class change its behavior in such a fundamental way, based solel=
y=20
>>> on how it was initialized, is not a "clean" method of coding. It makes =
it=20
>>> very difficult to look at a piece of code and statically know if it is=
=20
>>> reasonable.
>>>
>>>
>> For the case of `any`, it is already not so clean. It is the half-measur=
e=20
>> to grant false assumption about behavior of copy construction to users,=
=20
>> since the precise behavior may be not measurable at all - it can be=20
>> anything out of your control. Both disallowing copying totally and allow=
ing=20
>> copying + moving are more natural.
>>
>> Because it is named `any`, not `any_copyable`, it gives users extra=20
>> surprise.
>>
>
> That assumes the user would expect `any` (or any C++ type) to not be=20
> copyable. I fail to see how that's a valid assumption, considering that=
=20
> most C++ standard library types are copyable.
>
> Because of the wording. The type `any`, as the (most) general type-erased=
=20
type, has nothing to do with copyable or not. But since you may want to=20
allow passing it by value (as containers), it should at leas an object type=
..
Strictly speaking, even the "copy" itself has problem. A copy-constructible=
=20
type is copy-initializable. A movable but not copy-constructible type is=20
still copy-initializable. Is the copyable type copy-initializable or=20
copy-constructible? This was not a problem in C++98/03, but it is a problem=
=20
here. Copy constructor of `any` forwards the work to the contained object.=
=20
The strategy of copy (either deep, shallow, sharing, etc) is determined by=
=20
the copy constructor of contained object. Having assumption of the behavior=
=20
of the copy constructor seems to be not so useful, compared with "where it=
=20
can be used", at least to people who wants to provide the type signature=20
concerned with `any`.
=20
>>
>>> Also, it should be noted that it wouldn't be difficult at all to create=
=20
>>> a template wrapper type for non-copyable types, which will have a copy=
=20
>>> constructor but will throw if you try to use it. That would give you mo=
st=20
>>> of the effect you want.
>>>
>>> You would need `make_noncopyable_any<T>` to create such an `any` (if `T=
`=20
>>> is copyable, it won't wrap it). And you would need=20
>>> `noncopyable_any_cast<T>` to cast it back (it would first try getting t=
he=20
>>> wrapped `T`; if that failed, it would try to get `T` directly. That all=
ow=20
>>> `T` to be copyable). Both of which can be written outside of the class.
>>>
>>> So if you really, *truly* want this... you can still do it with `any`=
=20
>>> as it currently stands.
>>>
>>>
>> Good workaround. But no, how to initialize the wrapper?
>>
>
> Um... exactly like I said: `make_noncopyable_any`. This ain't rocket=20
> science here.=20
>
> What if an instance of `std::atomic`?
>>
>
> `any` can copy from a value or move from it. But it cannot take a value=
=20
> from a list of arguments and a type. You would need explicit emplacement=
=20
> construction support to do that, something like what P0032 proposes.
>
> But if you had that, then `make_noncopyable_any` would be able to work=20
> with immobile types too. There's nothing in the wrapper that would preven=
t=20
> that.
>
> That's also a good idea. Note I also mentioned emplacement, before I=20
realized there is P0032.
P0135 mandates the copy elision. If it is approved, then most of these=20
problem would not exist.
=20
> Why bother more indirect step to do the literally correct thing (to=20
>> initialize "any" object)?
>>
>
> What you want is not "the literally correct thing" *just because you=20
> declare it so*.
> =20
>
Well, the type *`any` does not declare it is copyable literally* *by its=20
name*, isn't it true?
=20
> If you think it is dangerous to allow noncopyable objects silently=20
>> initialize the `any` object, that's fair. You want to differentiate them=
..=20
>> OK. Let's have the compromise. Why should it be out of the interface of =
the=20
>> class `any`? Can you have a constructor template with a special tag to=
=20
>> indicate this use?
>>
>
> That's not a "compromise"; that's *surrender*.
>
> A "compromise" is where you get some of what you want, and I get some of=
=20
> what I want. By putting the wrapper directly into the interface of `any`,=
=20
> you get *everything* you want, and I get *nothing* I want.
>
> *What *do you want to get? To not modify the working draft?
Besides the assumption in your mind, do you actually *rely on* that any=20
will not throw during copying unless the contained object throws?
You can ignore what you does not need. Even if you want the type checking=
=20
for copy-constructible when the feature I want here has changed the=20
behavior of the constructor template `any`, just use `static_assert`. By=20
using additional tag type, it even does not force you to change your code=
=20
since you never use it at all. You only need one more explicit notice for=
=20
your clients (and yourself): if someone dare make the copy of `any`=20
actually throwing, the behavior of the program is not guaranteed=20
predictable. This* is *the status quo, *implicitly*.
This *is *the compromise because it allows you to pretend the problem does=
=20
not exist - that *is* your gain in the case when the interface has changed=
=20
and it does not break your code or limit you to write anything. It *is *a=
=20
surrender to keep `any` not changed for me, because *while the nominal=20
interface is disputable*, I actually lose something just because someone=20
else declared it is not cared and never used at all, and I eventually have=
=20
to *reinvent wheels* and pay for what I will not used after that (e.g. the=
=20
binary size of dynamic library of the standard library implementation).=20
Remember what the standard library is used for.
=20
> Remember: by creating this wrapped `any` instance, you're introducing=20
> *fragility* into your codebase. It should be clear and obvious when you=
=20
> do this, and it should not look like normal creation of an `any` instance=
..
>
This is not like normally because of your manner of creation, which is the=
=20
result. Once `any` is not `any_copyable` and the implicit rules of "use=20
copyable types" principle is not clarified by the standard clearly, this=20
should be normal.
=20
> It should *not happen by accident*.
>
> However, this is true, because any creation of `any` should not be the=20
most frequent operations within such a statically typed language. So is=20
`void*`. And I don't think I should only be able to do that with an=20
indirect layer to emphasize it in a strange, nonstandard way.=20
=20
> What I suggested is a compromise. My position is that nobody should be=20
> able to create an `any` instance which will always throw on copy. Your=20
> position is that `any` should be able to accept non-copyable or immobile=
=20
> types. The compromise is that, by default you can't use non-copyable type=
s.=20
> But you can use a wrapper to use non-copyable types, and there's nothing =
I=20
> can do to stop you.
> =20
>
>> Even not, should the wrapper be standardized?
>>
>
> Probably not. There would be some advantage to it; it would be more=20
> searchable, since everyone would not have different implementations.
>
My main point is to avoid to reinvent wheels for basic need that is easily=
=20
to met when not deliberately neglected. Though I agree with advantage of=20
searching.
=20
> But putting it in the standard also makes people think that using them is=
=20
> a good idea.
>
> No. Putting in the standard does not necessarily encourage using for=20
anyone, it may also just because:
- Being necessary to support the language implementation.
- To keep compatibility with the current practice.
- The non portable replacements can not work well in near future.
- To avoid too many wheels to be invented.
Not all of the reasons have the same effect to any interface.
People should have learned that they should use what they need.
=20
> However, no one was taught "any" should be copyable.=20
>>
>
> You mean besides everyone who has used `boost::any` for over a decade?
>
I don't use `boost::any` even if I would copy some reasonable design from=
=20
that (e.g. some names of member). That is trivial. I don't complain about=
=20
`boost::any` here, because it is prefixed with `boost::`, which indicates=
=20
it has no power to define *what *is C++, which is not I cared here. I can=
=20
ignore that design if I do not think it is good enough.
But all C++ users should face the standard, directly or indirectly, or they=
=20
were not learning C++, but a flavored dialect. Once an interface fixed in=
=20
the standard, the future change would cost probably much, not only in the=
=20
language, but also for implementations and mind of users.
=20
>
>> That's also why someone will be surprised.
>>
>
> I don't care.
>
> And you still cannot persuade me that the current design *has done the=20
right thing* undoubtfully, that means you can't assert a change will not be=
=20
considerable. Before you have proven anyone should not care it, it deserves=
..
=20
> Also, do you really want to argue "possible misconception to new users"?=
=20
>>> Don't you think users will find it far more surprising that a type that=
is=20
>>> supposedly copyable will emit an exception on copy for seemingly no rea=
son?=20
>>> Not to mention that such surprises will be *runtime errors*, rather=20
>>> than compile-time failures...
>>>
>>> They should not be so surprised if they know what type erasure stands=
=20
>> for.
>>
>
> ... what? The concept of type erasure has nothing at all to do with the=
=20
> behavior of a value type or reference type. You can make a type-erased=20
> copyable value type (aka: `any`). You can make a type-erased moveable val=
ue=20
> type (`unique_any`). You can make a type-erased non-owning reference type=
..=20
> You can make a type-erased owning reference type (`shared_any`). And so=
=20
> forth.
>
> The concept of type erasure does not in any way conflict with the concept=
=20
> of copying. So knowing about type erasure does not in any way require you=
=20
> to believe that a type-erased type would not be copyable. Again, see=20
> `std::function`.
>
It should not depend on copying, either. It should be the representative of=
=20
type-erased because of its naming, but why with unrelated limitations?
Function does not matter much because it is "function", not "any". Though=
=20
`std::function` is still not enough in practice, but it is another topic.
=20
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/be43d58f-39c5-4315-bba2-de9ec9e6aa96%40isocpp.or=
g.
------=_Part_8190_2130209821.1461839392904
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8827=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=8D=882:12:00=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Monday, April 25, 2016 at 7:29:07 AM UTC-4, FrankHB1989 wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=E5=9C=A8 2016=E5=
=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5 UTC+8=E4=B8=8A=E5=8D=
=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>How exactly does that cause a =
performance regression? The alternative to `any` is a `void*`. Which requir=
es heap allocation (or keeping around a pointer to a stack or global object=
). `void*` is not a value-type, so it's impossible to copy it.<br><br>I=
f you change your code from using `void*` to `any`, you would have no reaso=
n to suddenly decide to start copying `any` objects. Since that's an op=
eration that wasn't available before. So in both cases, the big object =
was heap allocated and in both cases, the object was not copied.<br><br>So =
where is the "performance regression"?<br><br>You would only get =
a "performance regression" if you completely changed the nature o=
f the code. And that would only happen if you aren't paying attention t=
o what you're doing.<br><br>Quite frankly, if you're not paying att=
ention to what you're doing in C++, you shouldn't be using the lang=
uage.<br><br></div></div></blockquote><div>You did not get the point.<br><b=
r>It is a side effect <i>after replacing a concrete type with `any`</i>.</d=
iv></div></blockquote><div><br>Stop. Why would you ever be doing that?<br><=
/div></div></blockquote><div>The similar reason to turning a concrete type =
to `void*`. <br></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"><div><br>`any` is a type-safe replacement for `void*`, not "a=
concrete type". So what is your code doing where you uses to take a s=
pecific type, and now you have decided to take anything? Especially when yo=
u were presumably taking that type as a by-value parameter (more on that la=
ter).<br><br></div></div></blockquote><div>But `void*` does not have the pr=
oblem.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>It seems to me that the type you would be interested in is `v=
ariant`.<br><br></div></div></blockquote><div>Yes I also need it, but it=
9;s elsewhere. I clearly know they are different.<br><br>And actually I nee=
d `any` does not only to replace `void*`. An object can have side effect in=
its destruction in a polymorphic way, which is not possible for `void*`.<b=
r><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div></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"><div>Bec=
ause `any` allows any "copy" occurs in its copy constructor liter=
ally, it is difficult to evaluate what the performance penalty it would be,=
particularly when the contained object is provided by the client code. Bec=
ause `any` does not limit it at all, users may easily do things you don'=
;t want, unless warned seriously (by some means not part of C++).<br></div>=
</div></blockquote><div><br>... maybe you haven't gotten the point yet,=
but <i>I don't care</i>.<br><br></div></div></blockquote><div>Whether =
you care or not, that problem may likely occur. I'm still not sure how =
your point can work around it.<br><br>My point here is that `any` does not =
fit for the work very well. If you are forced to use `any` in such a manner=
without control, something has already gone wrong. And you have to ignore =
this problem, if you insist on using `any` here anyway.<br>=C2=A0<br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>The fact=
that someone, somewhere, can misuse something to their performance detrime=
nt is not by itself sufficient reason to disallow it. `unique_ptr` disallow=
s copying because it conceptually makes no sense to copy something which is=
uniquely owned by this object. It's a logical contradiction and theref=
ore disallowed.<br><br>That's not the case with `any`.<br><br></div></d=
iv></blockquote><div>Yes. Allowing copy is the nature of `any` (at least in=
the current design). But this does not mean it is <i>suitable </i>to be co=
pied in general.<br>=C2=A0<br></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"><div></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"><div>Is this the mistake of users? Partially, but not all=
.. The design here is essentially doubtful. Usually, you would care about co=
py of containers so you should not pass the container by value. However, yo=
u seem to tend to a similar but worse choice for `any` here. Why?<br><br>Th=
e fact is, `any` cannot be used as a passed-by-value parameter type that ea=
sily.</div></div></blockquote><div><br>So what? Why are you so focused on u=
sing `any` as a "by-value parameter"? Nobody is suggesting that p=
eople should start writing APIs that take `any` instances as "by-value=
parameters". You are complaining about people doing something that no=
body actually wants to do.<br><br>Well, nobody except maybe you.<br><br></d=
iv></div></blockquote><div>Huh? Then what you were arguing about? If you do=
n't use `any` by-value, when will you copy it (frequently)?<br>=C2=A0<b=
r></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"><div>=
Do we tell people to take `vector` by value parameter? `optional`? `variant=
`? `std::function`? No. We generally tell people to take such types by refe=
rence.<br></div></div></blockquote><div>By taking reference, object of `any=
` is not copied. <br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div> Such use need extraordinary care, within limited use ca=
ses.</div></div></blockquote><div><br>Using a `const any&` is not "=
;extraordinary care". Nor does it limit use cases.<br>=C2=A0</div></di=
v></blockquote><div>Sure. That was about `any` passed by-value.<br>=C2=A0<b=
r></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"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div></div></blockquote><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"><div></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"><div>Nevertheless, the use of being passed by value is no=
t the killer feature of `any` at first. To use it as a data member has no s=
uch problems.</div></div></blockquote><div><br>It becomes a problem if it&#=
39;s a data member of a copyable type.<br></div></div></blockquote><div>If =
you want the enclosing class to be copyable, either limit access of this da=
ta member, or do not use the enclosing class as a function parameter at all=
..<br></div></div></blockquote><div><br>Again with the "function parame=
ter" stuff. You act like being a by-value parameter is the end-all-be-=
all of types.<br><br>It isn't.<br><br></div></div></blockquote><div>So =
why are you so interested in limiting the uniform behavior of copying? If i=
t is not used at implicit copy-initialization (mainly passing-by-value case=
s), is it still error-prone?<br>=C2=A0<br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div>Whether a type is copyable or not h=
as <i>nothing</i> to do with whether you should use it as a by-value parame=
ter or not. `vector` is copyable, but that doesn't mean you should copy=
it a lot.<br></div></div></blockquote><div><br>I have already mentioned th=
is.<br><br>If you agree that is comparable, why not force element of `vecto=
r` copyable? Just because the <i>implementation details</i> of type erasure=
need it to live or die in the whole type level for `any` while not for `ve=
ctor`?<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>=C2=A0</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"><div></div><div></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div></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"><div></div></div></blockquote><div>Not every type can be used by ever=
y person. No type fits every need. I'm sure people would really like to=
be able to store non-copyable functors in `std::function` too.<br>=C2=A0<b=
r></div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>I know I would.<br><br>But that doesn't mean that `std::f=
unction` is the type that should allow that.<br><br></div></div></blockquot=
e><div>A non-copyable function is not a traditional "function" (d=
ecayed as a function pointer). But the meaning of "any" diverges.=
<br></div></div></blockquote><div><br>Yes, `any` diverges from `void*`. Tha=
t's because `any` is designed to be a <i>safe</i> `void*`. It achieves =
this in two ways:<br><br>1. Casting is type-checked and will fail if the us=
er does not supply the actual type used to create the `any`.<br><br>2. The =
value stored is <i>owned</i> by the `any`, thus preventing any chance of th=
e object no longer being valid by the time it is recovered.<br><br>If you w=
ant to believe that people will expect `any` to provide #1 without #2, go a=
head.<br>=C2=A0</div></div></blockquote><div>True. But is this relevant to =
being copyable?<br>=C2=A0<br></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"><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"><div></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"><d=
iv></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div></blockquote></=
div></blockquote><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"><=
div>Having a class change its behavior in such a fundamental way, based sol=
ely on how it was initialized, is not a "clean" method of coding.=
It makes it very difficult to look at a piece of code and statically know =
if it is reasonable.<br><br></div></div></blockquote><div><br>For the case =
of `any`, it is already not so clean. It is the half-measure to grant false=
assumption about behavior of copy construction to users, since the precise=
behavior may be not measurable at all - it can be anything out of your con=
trol. Both disallowing copying totally and allowing copying + moving are mo=
re natural.<br><br>Because it is named `any`, not `any_copyable`, it gives =
users extra surprise.<br></div></div></blockquote><div><br>That assumes the=
user would expect `any` (or any C++ type) to not be copyable. I fail to se=
e how that's a valid assumption, considering that most C++ standard lib=
rary types are copyable.<br><br></div></div></blockquote><div>Because of th=
e wording. The type `any`, as the (most) general type-erased type, has noth=
ing to do with copyable or not. But since you may want to allow passing it =
by value (as containers), it should at leas an object type.<br><br>Strictly=
speaking, even the "copy" itself has problem. A copy-constructib=
le type is copy-initializable. A movable but not copy-constructible type is=
still copy-initializable. Is the copyable type copy-initializable or copy-=
constructible? This was not a problem in C++98/03, but it is a problem here=
.. Copy constructor of `any` forwards the work to the contained object. The =
strategy of copy (either deep, shallow, sharing, etc) is determined by the =
copy constructor of contained object. Having assumption of the behavior of =
the copy constructor seems to be not so useful, compared with "where i=
t can be used", at least to people who wants to provide the type signa=
ture concerned with `any`.<br><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div>=C2=A0<br></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"><div>Also, it should be noted that it wouldn't b=
e difficult at all to create a template wrapper type for non-copyable types=
, which will have a copy constructor but will throw if you try to use it. T=
hat would give you most of the effect you want.<br><br>You would need `make=
_noncopyable_any<T>` to create such an `any` (if `T` is copyable, it =
won't wrap it). And you would need `noncopyable_any_cast<T>` to c=
ast it back (it would first try getting the wrapped `T`; if that failed, it=
would try to get `T` directly. That allow `T` to be copyable). Both of whi=
ch can be written outside of the class.<br><br>So if you really, <i>truly</=
i> want this... you can still do it with `any` as it currently stands.<br><=
/div><div><br></div></div></blockquote><div><br>Good workaround. But no, ho=
w to initialize the wrapper?</div></div></blockquote><div><br>Um... exactly=
like I said: `make_noncopyable_any`. This ain't rocket science here. <=
br></div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div></div><div><br></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"><div> What if an instance of `std::atomic`?</div></d=
iv></blockquote><div><br>`any` can copy from a value or move from it. But i=
t cannot take a value from a list of arguments and a type. You would need e=
xplicit emplacement construction support to do that, something like what P0=
032 proposes.<br><br>But if you had that, then `make_noncopyable_any` would=
be able to work with immobile types too. There's nothing in the wrappe=
r that would prevent that.<br><br></div></div></blockquote><div>That's =
also a good idea. Note I also mentioned emplacement, before I realized ther=
e is P0032.<br><br>P0135 mandates the copy elision. If it is approved, then=
most of these problem would not exist.<br>=C2=A0<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>Why bother more indirect step =
to do the literally correct thing (to initialize "any" object)?<b=
r></div></div></blockquote><div><br>What you want is not "the literall=
y correct thing" <i>just because you declare it so</i>.<br>=C2=A0</div=
></div></blockquote><div>Well, the type <i>`any` does not declare it is cop=
yable literally</i> <i>by its name</i>, isn't it true?<br>=C2=A0<br></d=
iv><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"><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>If you think it is dang=
erous to allow noncopyable objects silently initialize the `any` object, th=
at's fair. You want to differentiate them. OK. Let's have the compr=
omise. Why should it be out of the interface of the class `any`? Can you ha=
ve a constructor template with a special tag to indicate this use?</div></d=
iv></blockquote><div><br>That's not a "compromise"; that'=
s <i>surrender</i>.<br><br>A "compromise" is where you get some o=
f what you want, and I get some of what I want. By putting the wrapper dire=
ctly into the interface of `any`, you get <i>everything</i> you want, and I=
get <i>nothing</i> I want.<br><br></div></div></blockquote><div><i>What </=
i>do you want to get? To not modify the working draft?<br><br>Besides the a=
ssumption in your mind, do you actually <i>rely on</i> that any will not th=
row during copying unless the contained object throws?<br><br>You can ignor=
e what you does not need. Even if you want the type checking for copy-const=
ructible when the feature I want here has changed the behavior of the const=
ructor template `any`, just use `static_assert`. By using additional tag ty=
pe, it even does not force you to change your code since you never use it a=
t all. You only need one more explicit notice for your clients (and yoursel=
f): if someone dare make the copy of `any` actually throwing, the behavior =
of the program is not guaranteed predictable. This<i> is </i>the status quo=
, <i>implicitly</i>.<br><br>This <i>is </i>the compromise because it allows=
you to pretend the problem does not exist - that <i>is</i> your gain in th=
e case when the interface has changed and it does not break your code or li=
mit you to write anything. It <i>is </i>a surrender to keep `any` not chang=
ed for me, because <i>while the nominal interface is disputable</i>, I actu=
ally lose something just because someone else declared it is not cared and =
never used at all, and I eventually have to <i>reinvent wheels</i> and pay =
for what I will not used after that (e.g. the binary size of dynamic librar=
y of the standard library implementation). Remember what the standard libra=
ry is used for.<br>=C2=A0<br></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"><div>Remember: by creating this wrapped `any` instan=
ce, you're introducing <i>fragility</i> into your codebase. It should b=
e clear and obvious when you do this, and it should not look like normal cr=
eation of an `any` instance.</div></div></blockquote><div><br>This is not l=
ike normally because of your manner of creation, which is the result. Once =
`any` is not `any_copyable` and the implicit rules of "use copyable ty=
pes" principle is not clarified by the standard clearly, this should b=
e normal.<br>=C2=A0</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"><div>It should <i>not happen by accident</i>.<br><br></div></di=
v></blockquote><div>However, this is true, because any creation of `any` sh=
ould not be the most frequent operations within such a statically typed lan=
guage. So is `void*`. And I don't think I should only be able to do tha=
t with an indirect layer to emphasize it in a strange, nonstandard way. <br=
></div><div>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div>What I suggested is a compromise. My position is that n=
obody should be able to create an `any` instance which will always throw on=
copy. Your position is that `any` should be able to accept non-copyable or=
immobile types. The compromise is that, by default you can't use non-c=
opyable types. But you can use a wrapper to use non-copyable types, and the=
re's nothing I can do to stop you.<br>=C2=A0</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"><div>Even not, should the wrapper be st=
andardized?<br></div></div></blockquote><div><br>Probably not. There would =
be some advantage to it; it would be more searchable, since everyone would =
not have different implementations.</div></div></blockquote><div>My main po=
int is to avoid to reinvent wheels for basic need that is easily to met whe=
n not deliberately neglected. Though I agree with advantage of searching.<b=
r>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div>But putting it in the standard also makes people think that using=
them is a good idea.<br><br></div></div></blockquote><div>No. Putting in t=
he standard does not necessarily encourage using for anyone, it may also ju=
st because:<br><br>- Being necessary to support the language implementation=
..<br>- To keep compatibility with the current practice.<br>- The non portab=
le replacements can not work well in near future.<br>- To avoid too many wh=
eels to be invented.<br><br>Not all of the reasons have the same effect to =
any interface.<br><br>People should have learned that they should use what =
they need.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>However, no one was taught "any" should be copyabl=
e. <br></div></div></blockquote><div><br>You mean besides everyone who has =
used `boost::any` for over a decade?<br></div></div></blockquote><div><br>I=
don't use `boost::any` even if I would copy some reasonable design fro=
m that (e.g. some names of member). That is trivial. I don't complain a=
bout `boost::any` here, because it is prefixed with `boost::`, which indica=
tes it has no power to define <i>what </i>is C++, which is not I cared here=
.. I can ignore that design if I do not think it is good enough.<br><br>But =
all C++ users should face the standard, directly or indirectly, or they wer=
e not learning C++, but a flavored dialect. Once an interface fixed in the =
standard, the future change would cost probably much, not only in the langu=
age, but also for implementations and mind of users.<br><br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div> That's also w=
hy someone will be surprised.<br></div></div></blockquote><div><br>I don=
9;t care.<br><br></div></div></blockquote><div>And you still cannot persuad=
e me that the current design <i>has done the right thing</i> undoubtfully, =
that means you can't assert a change will not be considerable. Before y=
ou have proven anyone should not care it, it deserves.<br>=C2=A0<br></div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Also, do you really wan=
t to argue "possible misconception to new users"? Don't you t=
hink users will find it far more surprising that a type that is supposedly =
copyable will emit an exception on copy for seemingly no reason? Not to men=
tion that such surprises will be <i>runtime errors</i>, rather than compile=
-time failures...<br><br></div></div></blockquote><div>They should not be s=
o surprised if they know what type erasure stands for.<br></div></div></blo=
ckquote><div><br>... what? The concept of type erasure has nothing at all t=
o do with the behavior of a value type or reference type. You can make a ty=
pe-erased copyable value type (aka: `any`). You can make a type-erased move=
able value type (`unique_any`). You can make a type-erased non-owning refer=
ence type. You can make a type-erased owning reference type (`shared_any`).=
And so forth.<br><br>The concept of type erasure does not in any way confl=
ict with the concept of copying. So knowing about type erasure does not in =
any way require you to believe that a type-erased type would not be copyabl=
e. Again, see `std::function`.</div></div></blockquote><div>It should not d=
epend on copying, either. It should be the representative of type-erased be=
cause of its naming, but why with unrelated limitations?<br>Function does n=
ot matter much because it is "function", not "any". Tho=
ugh `std::function` is still not enough in practice, but it is another topi=
c.<br>=C2=A0<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/be43d58f-39c5-4315-bba2-de9ec9e6aa96%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/be43d58f-39c5-4315-bba2-de9ec9e6aa96=
%40isocpp.org</a>.<br />
------=_Part_8190_2130209821.1461839392904--
------=_Part_8189_1281704516.1461839392903--
.
Author: Brent Friedman <fourthgeek@gmail.com>
Date: Thu, 28 Apr 2016 21:59:31 -0500
Raw View
--001a114b1588fe3106053196d440
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
>
> I think it will be useful to allow noncopyable values in the constructor
> template
This is a long thread, but I don't think the following solution has been
considered. It transforms noncopyable types to copyable types by throwing.
It seems like it resolves the issue without changes to any. I think it
should allow you to use noncopyable types with all containers as long as
the containers provide the necessary exception guarantees. What do you
think?
struct noncopyable_exception {};
template<class T>
struct throw_on_copy
{
T data;
template<class... Args>
throw_on_copy(Args... args)
:data(std::forward<Args>(args)...)
{
}
throw_on_copy(const throw_on_copy&)
{
throw noncopyable_exception{};
}
throw_on_copy(throw_on_copy&&)=3Ddefault;
throw_on_copy& operator=3D(const throw_on_copy&)
{
throw noncopyable_exception{};
}
throw_on_copy& operator=3D(throw_on_copy&&) =3D default;
};
std::any v{ throw_on_copy<my_noncopyable_type>{arg0,arg1,arg2} };
On Thu, Apr 28, 2016 at 5:29 AM, FrankHB1989 <frankhb1989@gmail.com> wrote:
>
>
> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8827=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 U=
TC+8=E4=B8=8A=E5=8D=882:12:00=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>
>> On Monday, April 25, 2016 at 7:29:07 AM UTC-4, FrankHB1989 wrote:
>>>
>>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5=
UTC+8=E4=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=
=BC=9A
>>>>
>>>> How exactly does that cause a performance regression? The alternative
>>>> to `any` is a `void*`. Which requires heap allocation (or keeping arou=
nd a
>>>> pointer to a stack or global object). `void*` is not a value-type, so =
it's
>>>> impossible to copy it.
>>>>
>>>> If you change your code from using `void*` to `any`, you would have no
>>>> reason to suddenly decide to start copying `any` objects. Since that's=
an
>>>> operation that wasn't available before. So in both cases, the big obje=
ct
>>>> was heap allocated and in both cases, the object was not copied.
>>>>
>>>> So where is the "performance regression"?
>>>>
>>>> You would only get a "performance regression" if you completely change=
d
>>>> the nature of the code. And that would only happen if you aren't payin=
g
>>>> attention to what you're doing.
>>>>
>>>> Quite frankly, if you're not paying attention to what you're doing in
>>>> C++, you shouldn't be using the language.
>>>>
>>>> You did not get the point.
>>>
>>> It is a side effect *after replacing a concrete type with `any`*.
>>>
>>
>> Stop. Why would you ever be doing that?
>>
> The similar reason to turning a concrete type to `void*`.
>
>>
>> `any` is a type-safe replacement for `void*`, not "a concrete type". So
>> what is your code doing where you uses to take a specific type, and now =
you
>> have decided to take anything? Especially when you were presumably takin=
g
>> that type as a by-value parameter (more on that later).
>>
>> But `void*` does not have the problem.
>
> It seems to me that the type you would be interested in is `variant`.
>>
>> Yes I also need it, but it's elsewhere. I clearly know they are differen=
t.
>
> And actually I need `any` does not only to replace `void*`. An object can
> have side effect in its destruction in a polymorphic way, which is not
> possible for `void*`.
>
> Because `any` allows any "copy" occurs in its copy constructor literally,
>>> it is difficult to evaluate what the performance penalty it would be,
>>> particularly when the contained object is provided by the client code.
>>> Because `any` does not limit it at all, users may easily do things you
>>> don't want, unless warned seriously (by some means not part of C++).
>>>
>>
>> ... maybe you haven't gotten the point yet, but *I don't care*.
>>
>> Whether you care or not, that problem may likely occur. I'm still not
> sure how your point can work around it.
>
> My point here is that `any` does not fit for the work very well. If you
> are forced to use `any` in such a manner without control, something has
> already gone wrong. And you have to ignore this problem, if you insist on
> using `any` here anyway.
>
>
>> The fact that someone, somewhere, can misuse something to their
>> performance detriment is not by itself sufficient reason to disallow it.
>> `unique_ptr` disallows copying because it conceptually makes no sense to
>> copy something which is uniquely owned by this object. It's a logical
>> contradiction and therefore disallowed.
>>
>> That's not the case with `any`.
>>
>> Yes. Allowing copy is the nature of `any` (at least in the current
> design). But this does not mean it is *suitable *to be copied in general.
>
>
>> Is this the mistake of users? Partially, but not all. The design here is
>>> essentially doubtful. Usually, you would care about copy of containers =
so
>>> you should not pass the container by value. However, you seem to tend t=
o a
>>> similar but worse choice for `any` here. Why?
>>>
>>> The fact is, `any` cannot be used as a passed-by-value parameter type
>>> that easily.
>>>
>>
>> So what? Why are you so focused on using `any` as a "by-value parameter"=
?
>> Nobody is suggesting that people should start writing APIs that take `an=
y`
>> instances as "by-value parameters". You are complaining about people doi=
ng
>> something that nobody actually wants to do.
>>
>> Well, nobody except maybe you.
>>
>> Huh? Then what you were arguing about? If you don't use `any` by-value,
> when will you copy it (frequently)?
>
>
>> Do we tell people to take `vector` by value parameter? `optional`?
>> `variant`? `std::function`? No. We generally tell people to take such ty=
pes
>> by reference.
>>
> By taking reference, object of `any` is not copied.
>
>>
>>
>>> Such use need extraordinary care, within limited use cases.
>>>
>>
>> Using a `const any&` is not "extraordinary care". Nor does it limit use
>> cases.
>>
>>
> Sure. That was about `any` passed by-value.
>
>
>> Nevertheless, the use of being passed by value is not the killer feature
>>>>> of `any` at first. To use it as a data member has no such problems.
>>>>>
>>>>
>>>> It becomes a problem if it's a data member of a copyable type.
>>>>
>>> If you want the enclosing class to be copyable, either limit access of
>>> this data member, or do not use the enclosing class as a function param=
eter
>>> at all.
>>>
>>
>> Again with the "function parameter" stuff. You act like being a by-value
>> parameter is the end-all-be-all of types.
>>
>> It isn't.
>>
>> So why are you so interested in limiting the uniform behavior of copying=
?
> If it is not used at implicit copy-initialization (mainly passing-by-valu=
e
> cases), is it still error-prone?
>
>
>> Whether a type is copyable or not has *nothing* to do with whether you
>> should use it as a by-value parameter or not. `vector` is copyable, but
>> that doesn't mean you should copy it a lot.
>>
>
> I have already mentioned this.
>
> If you agree that is comparable, why not force element of `vector`
> copyable? Just because the *implementation details* of type erasure need
> it to live or die in the whole type level for `any` while not for `vector=
`?
>
>
>>
>>> Not every type can be used by every person. No type fits every need. I'=
m
>>>> sure people would really like to be able to store non-copyable functor=
s in
>>>> `std::function` too.
>>>>
>>>>
>>> I know I would.
>>>>
>>>> But that doesn't mean that `std::function` is the type that should
>>>> allow that.
>>>>
>>>> A non-copyable function is not a traditional "function" (decayed as a
>>> function pointer). But the meaning of "any" diverges.
>>>
>>
>> Yes, `any` diverges from `void*`. That's because `any` is designed to be
>> a *safe* `void*`. It achieves this in two ways:
>>
>> 1. Casting is type-checked and will fail if the user does not supply the
>> actual type used to create the `any`.
>>
>> 2. The value stored is *owned* by the `any`, thus preventing any chance
>> of the object no longer being valid by the time it is recovered.
>>
>> If you want to believe that people will expect `any` to provide #1
>> without #2, go ahead.
>>
>>
> True. But is this relevant to being copyable?
>
>
>> Having a class change its behavior in such a fundamental way, based
>>>> solely on how it was initialized, is not a "clean" method of coding. I=
t
>>>> makes it very difficult to look at a piece of code and statically know=
if
>>>> it is reasonable.
>>>>
>>>>
>>> For the case of `any`, it is already not so clean. It is the
>>> half-measure to grant false assumption about behavior of copy construct=
ion
>>> to users, since the precise behavior may be not measurable at all - it =
can
>>> be anything out of your control. Both disallowing copying totally and
>>> allowing copying + moving are more natural.
>>>
>>> Because it is named `any`, not `any_copyable`, it gives users extra
>>> surprise.
>>>
>>
>> That assumes the user would expect `any` (or any C++ type) to not be
>> copyable. I fail to see how that's a valid assumption, considering that
>> most C++ standard library types are copyable.
>>
>> Because of the wording. The type `any`, as the (most) general type-erase=
d
> type, has nothing to do with copyable or not. But since you may want to
> allow passing it by value (as containers), it should at leas an object ty=
pe.
>
> Strictly speaking, even the "copy" itself has problem. A
> copy-constructible type is copy-initializable. A movable but not
> copy-constructible type is still copy-initializable. Is the copyable type
> copy-initializable or copy-constructible? This was not a problem in
> C++98/03, but it is a problem here. Copy constructor of `any` forwards th=
e
> work to the contained object. The strategy of copy (either deep, shallow,
> sharing, etc) is determined by the copy constructor of contained object.
> Having assumption of the behavior of the copy constructor seems to be not
> so useful, compared with "where it can be used", at least to people who
> wants to provide the type signature concerned with `any`.
>
>
>>>
>>>> Also, it should be noted that it wouldn't be difficult at all to creat=
e
>>>> a template wrapper type for non-copyable types, which will have a copy
>>>> constructor but will throw if you try to use it. That would give you m=
ost
>>>> of the effect you want.
>>>>
>>>> You would need `make_noncopyable_any<T>` to create such an `any` (if
>>>> `T` is copyable, it won't wrap it). And you would need
>>>> `noncopyable_any_cast<T>` to cast it back (it would first try getting =
the
>>>> wrapped `T`; if that failed, it would try to get `T` directly. That al=
low
>>>> `T` to be copyable). Both of which can be written outside of the class=
..
>>>>
>>>> So if you really, *truly* want this... you can still do it with `any`
>>>> as it currently stands.
>>>>
>>>>
>>> Good workaround. But no, how to initialize the wrapper?
>>>
>>
>> Um... exactly like I said: `make_noncopyable_any`. This ain't rocket
>> science here.
>>
>
>> What if an instance of `std::atomic`?
>>>
>>
>> `any` can copy from a value or move from it. But it cannot take a value
>> from a list of arguments and a type. You would need explicit emplacement
>> construction support to do that, something like what P0032 proposes.
>>
>> But if you had that, then `make_noncopyable_any` would be able to work
>> with immobile types too. There's nothing in the wrapper that would preve=
nt
>> that.
>>
>> That's also a good idea. Note I also mentioned emplacement, before I
> realized there is P0032.
>
> P0135 mandates the copy elision. If it is approved, then most of these
> problem would not exist.
>
>
>> Why bother more indirect step to do the literally correct thing (to
>>> initialize "any" object)?
>>>
>>
>> What you want is not "the literally correct thing" *just because you
>> declare it so*.
>>
>>
> Well, the type *`any` does not declare it is copyable literally* *by its
> name*, isn't it true?
>
>
>> If you think it is dangerous to allow noncopyable objects silently
>>> initialize the `any` object, that's fair. You want to differentiate the=
m.
>>> OK. Let's have the compromise. Why should it be out of the interface of=
the
>>> class `any`? Can you have a constructor template with a special tag to
>>> indicate this use?
>>>
>>
>> That's not a "compromise"; that's *surrender*.
>>
>> A "compromise" is where you get some of what you want, and I get some of
>> what I want. By putting the wrapper directly into the interface of `any`=
,
>> you get *everything* you want, and I get *nothing* I want.
>>
>> *What *do you want to get? To not modify the working draft?
>
> Besides the assumption in your mind, do you actually *rely on* that any
> will not throw during copying unless the contained object throws?
>
> You can ignore what you does not need. Even if you want the type checking
> for copy-constructible when the feature I want here has changed the
> behavior of the constructor template `any`, just use `static_assert`. By
> using additional tag type, it even does not force you to change your code
> since you never use it at all. You only need one more explicit notice for
> your clients (and yourself): if someone dare make the copy of `any`
> actually throwing, the behavior of the program is not guaranteed
> predictable. This* is *the status quo, *implicitly*.
>
> This *is *the compromise because it allows you to pretend the problem
> does not exist - that *is* your gain in the case when the interface has
> changed and it does not break your code or limit you to write anything. I=
t *is
> *a surrender to keep `any` not changed for me, because *while the nominal
> interface is disputable*, I actually lose something just because someone
> else declared it is not cared and never used at all, and I eventually hav=
e
> to *reinvent wheels* and pay for what I will not used after that (e.g.
> the binary size of dynamic library of the standard library implementation=
).
> Remember what the standard library is used for.
>
>
>> Remember: by creating this wrapped `any` instance, you're introducing
>> *fragility* into your codebase. It should be clear and obvious when you
>> do this, and it should not look like normal creation of an `any` instanc=
e.
>>
>
> This is not like normally because of your manner of creation, which is th=
e
> result. Once `any` is not `any_copyable` and the implicit rules of "use
> copyable types" principle is not clarified by the standard clearly, this
> should be normal.
>
>
>> It should *not happen by accident*.
>>
>> However, this is true, because any creation of `any` should not be the
> most frequent operations within such a statically typed language. So is
> `void*`. And I don't think I should only be able to do that with an
> indirect layer to emphasize it in a strange, nonstandard way.
>
>
>> What I suggested is a compromise. My position is that nobody should be
>> able to create an `any` instance which will always throw on copy. Your
>> position is that `any` should be able to accept non-copyable or immobile
>> types. The compromise is that, by default you can't use non-copyable typ=
es.
>> But you can use a wrapper to use non-copyable types, and there's nothing=
I
>> can do to stop you.
>>
>>
>>> Even not, should the wrapper be standardized?
>>>
>>
>> Probably not. There would be some advantage to it; it would be more
>> searchable, since everyone would not have different implementations.
>>
> My main point is to avoid to reinvent wheels for basic need that is easil=
y
> to met when not deliberately neglected. Though I agree with advantage of
> searching.
>
>
>> But putting it in the standard also makes people think that using them i=
s
>> a good idea.
>>
>> No. Putting in the standard does not necessarily encourage using for
> anyone, it may also just because:
>
> - Being necessary to support the language implementation.
> - To keep compatibility with the current practice.
> - The non portable replacements can not work well in near future.
> - To avoid too many wheels to be invented.
>
> Not all of the reasons have the same effect to any interface.
>
> People should have learned that they should use what they need.
>
>
>> However, no one was taught "any" should be copyable.
>>>
>>
>> You mean besides everyone who has used `boost::any` for over a decade?
>>
>
> I don't use `boost::any` even if I would copy some reasonable design from
> that (e.g. some names of member). That is trivial. I don't complain about
> `boost::any` here, because it is prefixed with `boost::`, which indicates
> it has no power to define *what *is C++, which is not I cared here. I can
> ignore that design if I do not think it is good enough.
>
> But all C++ users should face the standard, directly or indirectly, or
> they were not learning C++, but a flavored dialect. Once an interface fix=
ed
> in the standard, the future change would cost probably much, not only in
> the language, but also for implementations and mind of users.
>
>
>>
>>> That's also why someone will be surprised.
>>>
>>
>> I don't care.
>>
>> And you still cannot persuade me that the current design *has done the
> right thing* undoubtfully, that means you can't assert a change will not
> be considerable. Before you have proven anyone should not care it, it
> deserves.
>
>
>> Also, do you really want to argue "possible misconception to new users"?
>>>> Don't you think users will find it far more surprising that a type tha=
t is
>>>> supposedly copyable will emit an exception on copy for seemingly no re=
ason?
>>>> Not to mention that such surprises will be *runtime errors*, rather
>>>> than compile-time failures...
>>>>
>>>> They should not be so surprised if they know what type erasure stands
>>> for.
>>>
>>
>> ... what? The concept of type erasure has nothing at all to do with the
>> behavior of a value type or reference type. You can make a type-erased
>> copyable value type (aka: `any`). You can make a type-erased moveable va=
lue
>> type (`unique_any`). You can make a type-erased non-owning reference typ=
e.
>> You can make a type-erased owning reference type (`shared_any`). And so
>> forth.
>>
>> The concept of type erasure does not in any way conflict with the concep=
t
>> of copying. So knowing about type erasure does not in any way require yo=
u
>> to believe that a type-erased type would not be copyable. Again, see
>> `std::function`.
>>
> It should not depend on copying, either. It should be the representative
> of type-erased because of its naming, but why with unrelated limitations?
> Function does not matter much because it is "function", not "any". Though
> `std::function` is still not enough in practice, but it is another topic.
>
>
> --
> 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/be43d58f-39c=
5-4315-bba2-de9ec9e6aa96%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/be43d58f-39=
c5-4315-bba2-de9ec9e6aa96%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
--=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/CADbh%2BeQYGdYQy1Uacx8z%2BUcC4kBJq3icB7ZsqZOH_kb=
Yy0TZXA%40mail.gmail.com.
--001a114b1588fe3106053196d440
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-l=
eft-style:solid;padding-left:1ex"><span style=3D"font-size:12.8px">I think =
it will be useful to allow noncopyable values in the constructor template</=
span></blockquote><div><br></div><div>This is a long thread, but I don'=
t think the following solution has been considered. It transforms noncopyab=
le types to copyable types by throwing. It seems like it resolves the issue=
without changes to any. I think it should allow you to use noncopyable typ=
es with all containers as long as the containers provide the necessary exce=
ption guarantees. What do you think?</div><div><br></div><blockquote style=
=3D"margin:0 0 0 40px;border:none;padding:0px"><div><div>struct noncopyable=
_exception {};</div></div><div><div><br></div></div><div><div>template<c=
lass T></div></div><div><div>struct throw_on_copy</div></div><div><div>{=
</div></div><div><div><span class=3D"" style=3D"white-space:pre"> </span>T =
data;</div></div><div><div><span class=3D"" style=3D"white-space:pre"> </sp=
an>template<class... Args></div></div><div><div><span class=3D"" styl=
e=3D"white-space:pre"> </span>throw_on_copy(Args... args)</div></div><div><=
div><span class=3D"" style=3D"white-space:pre"> </span>:data(std::forward&=
lt;Args>(args)...)</div></div><div><div><span class=3D"" style=3D"white-=
space:pre"> </span>{</div></div><div><div><span class=3D"" style=3D"white-s=
pace:pre"> </span>}</div></div><div><div><span class=3D"" style=3D"white-sp=
ace:pre"> </span>throw_on_copy(const throw_on_copy&)</div></div><div><d=
iv><span class=3D"" style=3D"white-space:pre"> </span>{</div></div><div><di=
v><span class=3D"" style=3D"white-space:pre"> </span>throw noncopyable_exc=
eption{};</div></div><div><div><span class=3D"" style=3D"white-space:pre"> =
</span>}</div></div><div><div><span class=3D"" style=3D"white-space:pre"> <=
/span>throw_on_copy(throw_on_copy&&)=3Ddefault;</div></div><div><di=
v><br></div></div><div><div><span class=3D"" style=3D"white-space:pre"> </s=
pan>throw_on_copy& operator=3D(const throw_on_copy&)</div></div><di=
v><div><span class=3D"" style=3D"white-space:pre"> </span>{</div></div><div=
><div><span class=3D"" style=3D"white-space:pre"> </span>throw noncopyable=
_exception{};</div></div><div><div><span class=3D"" style=3D"white-space:pr=
e"> </span>}</div></div><div><div><span class=3D"" style=3D"white-space:pre=
"> </span>throw_on_copy& operator=3D(throw_on_copy&&) =3D defau=
lt;</div></div><div><div>};</div></div><div><br></div><div>std::any v{ thro=
w_on_copy<my_noncopyable_type>{arg0,arg1,arg2} };</div></blockquote><=
div><br></div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quot=
e">On Thu, Apr 28, 2016 at 5:29 AM, FrankHB1989 <span dir=3D"ltr"><<a hr=
ef=3D"mailto:frankhb1989@gmail.com" target=3D"_blank">frankhb1989@gmail.com=
</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><=
br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8827=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=
=89 UTC+8=E4=B8=8A=E5=8D=882:12:00=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=
=BC=9A<span class=3D""><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 Monday, April 25, 2016 at 7:29:07 AM UTC-4, FrankHB1989 wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=E5=9C=A8 2016=E5=B9=B4=
4=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5 UTC+8=E4=B8=8A=E5=8D=8811:=
36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>How exactly does that cause a perfor=
mance regression? The alternative to `any` is a `void*`. Which requires hea=
p allocation (or keeping around a pointer to a stack or global object). `vo=
id*` is not a value-type, so it's impossible to copy it.<br><br>If you =
change your code from using `void*` to `any`, you would have no reason to s=
uddenly decide to start copying `any` objects. Since that's an operatio=
n that wasn't available before. So in both cases, the big object was he=
ap allocated and in both cases, the object was not copied.<br><br>So where =
is the "performance regression"?<br><br>You would only get a &quo=
t;performance regression" if you completely changed the nature of the =
code. And that would only happen if you aren't paying attention to what=
you're doing.<br><br>Quite frankly, if you're not paying attention=
to what you're doing in C++, you shouldn't be using the language.<=
br><br></div></div></blockquote><div>You did not get the point.<br><br>It i=
s a side effect <i>after replacing a concrete type with `any`</i>.</div></d=
iv></blockquote><div><br>Stop. Why would you ever be doing that?<br></div><=
/div></blockquote></span><div>The similar reason to turning a concrete type=
to `void*`. <br></div><span class=3D""><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div><br>`any` is a type-safe replacement for `void*`=
, not "a concrete type". So what is your code doing where you use=
s to take a specific type, and now you have decided to take anything? Espec=
ially when you were presumably taking that type as a by-value parameter (mo=
re on that later).<br><br></div></div></blockquote></span><div>But `void*` =
does not have the problem.<br><br></div><span class=3D""><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>It seems to me that the type y=
ou would be interested in is `variant`.<br><br></div></div></blockquote></s=
pan><div>Yes I also need it, but it's elsewhere. I clearly know they ar=
e different.<br><br>And actually I need `any` does not only to replace `voi=
d*`. An object can have side effect in its destruction in a polymorphic way=
, which is not possible for `void*`.<br><br></div><span class=3D""><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
solid;padding-left:1ex"><div dir=3D"ltr"><div>Because `any` allows any &qu=
ot;copy" occurs in its copy constructor literally, it is difficult to =
evaluate what the performance penalty it would be, particularly when the co=
ntained object is provided by the client code. Because `any` does not limit=
it at all, users may easily do things you don't want, unless warned se=
riously (by some means not part of C++).<br></div></div></blockquote><div><=
br>... maybe you haven't gotten the point yet, but <i>I don't care<=
/i>.<br><br></div></div></blockquote></span><div>Whether you care or not, t=
hat problem may likely occur. I'm still not sure how your point can wor=
k around it.<br><br>My point here is that `any` does not fit for the work v=
ery well. If you are forced to use `any` in such a manner without control, =
something has already gone wrong. And you have to ignore this problem, if y=
ou insist on using `any` here anyway.<br>=C2=A0<br></div><span class=3D""><=
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"><div>The fact that =
someone, somewhere, can misuse something to their performance detriment is =
not by itself sufficient reason to disallow it. `unique_ptr` disallows copy=
ing because it conceptually makes no sense to copy something which is uniqu=
ely owned by this object. It's a logical contradiction and therefore di=
sallowed.<br><br>That's not the case with `any`.<br><br></div></div></b=
lockquote></span><div>Yes. Allowing copy is the nature of `any` (at least i=
n the current design). But this does not mean it is <i>suitable </i>to be c=
opied in general.<br>=C2=A0<br></div><span class=3D""><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"><div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div>Is this the mistake of users? Partially, =
but not all. The design here is essentially doubtful. Usually, you would ca=
re about copy of containers so you should not pass the container by value. =
However, you seem to tend to a similar but worse choice for `any` here. Why=
?<br><br>The fact is, `any` cannot be used as a passed-by-value parameter t=
ype that easily.</div></div></blockquote><div><br>So what? Why are you so f=
ocused on using `any` as a "by-value parameter"? Nobody is sugges=
ting that people should start writing APIs that take `any` instances as &qu=
ot;by-value parameters". You are complaining about people doing someth=
ing that nobody actually wants to do.<br><br>Well, nobody except maybe you.=
<br><br></div></div></blockquote></span><div>Huh? Then what you were arguin=
g about? If you don't use `any` by-value, when will you copy it (freque=
ntly)?<br>=C2=A0<br></div><span class=3D""><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>Do we tell people to take `vector` by value p=
arameter? `optional`? `variant`? `std::function`? No. We generally tell peo=
ple to take such types by reference.<br></div></div></blockquote></span><di=
v>By taking reference, object of `any` is not copied. <br></div><span class=
=3D""><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"><div>=C2=A0<=
/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"><div> Such us=
e need extraordinary care, within limited use cases.</div></div></blockquo=
te><div><br>Using a `const any&` is not "extraordinary care".=
Nor does it limit use cases.<br>=C2=A0</div></div></blockquote></span><div=
>Sure. That was about `any` passed by-value.<br>=C2=A0<br></div><span class=
=3D""><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"><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"><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div></div></blockquote><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"><div></div><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>Nevertheless, the use of being passed by value is not the k=
iller feature of `any` at first. To use it as a data member has no such pro=
blems.</div></div></blockquote><div><br>It becomes a problem if it's a =
data member of a copyable type.<br></div></div></blockquote><div>If you wan=
t the enclosing class to be copyable, either limit access of this data memb=
er, or do not use the enclosing class as a function parameter at all.<br></=
div></div></blockquote><div><br>Again with the "function parameter&quo=
t; stuff. You act like being a by-value parameter is the end-all-be-all of =
types.<br><br>It isn't.<br><br></div></div></blockquote></span><div>So =
why are you so interested in limiting the uniform behavior of copying? If i=
t is not used at implicit copy-initialization (mainly passing-by-value case=
s), is it still error-prone?<br>=C2=A0<br></div><span class=3D""><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Whether a type is copya=
ble or not has <i>nothing</i> to do with whether you should use it as a by-=
value parameter or not. `vector` is copyable, but that doesn't mean you=
should copy it a lot.<br></div></div></blockquote></span><div><br>I have a=
lready mentioned this.<br><br>If you agree that is comparable, why not forc=
e element of `vector` copyable? Just because the <i>implementation details<=
/i> of type erasure need it to live or die in the whole type level for `any=
` while not for `vector`?<br><br></div><span class=3D""><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div></div></div></blockquote><div>Not=
every type can be used by every person. No type fits every need. I'm s=
ure people would really like to be able to store non-copyable functors in `=
std::function` too.<br>=C2=A0<br></div></div></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>I know I would.<br><br>But tha=
t doesn't mean that `std::function` is the type that should allow that.=
<br><br></div></div></blockquote><div>A non-copyable function is not a trad=
itional "function" (decayed as a function pointer). But the meani=
ng of "any" diverges.<br></div></div></blockquote><div><br>Yes, `=
any` diverges from `void*`. That's because `any` is designed to be a <i=
>safe</i> `void*`. It achieves this in two ways:<br><br>1. Casting is type-=
checked and will fail if the user does not supply the actual type used to c=
reate the `any`.<br><br>2. The value stored is <i>owned</i> by the `any`, t=
hus preventing any chance of the object no longer being valid by the time i=
t is recovered.<br><br>If you want to believe that people will expect `any`=
to provide #1 without #2, go ahead.<br>=C2=A0</div></div></blockquote></sp=
an><div>True. But is this relevant to being copyable?<br>=C2=A0<br></div><s=
pan class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div></div></blockquote></div></blockquote><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Having a class change =
its behavior in such a fundamental way, based solely on how it was initiali=
zed, is not a "clean" method of coding. It makes it very difficul=
t to look at a piece of code and statically know if it is reasonable.<br><b=
r></div></div></blockquote><div><br>For the case of `any`, it is already no=
t so clean. It is the half-measure to grant false assumption about behavior=
of copy construction to users, since the precise behavior may be not measu=
rable at all - it can be anything out of your control. Both disallowing cop=
ying totally and allowing copying + moving are more natural.<br><br>Because=
it is named `any`, not `any_copyable`, it gives users extra surprise.<br><=
/div></div></blockquote><div><br>That assumes the user would expect `any` (=
or any C++ type) to not be copyable. I fail to see how that's a valid a=
ssumption, considering that most C++ standard library types are copyable.<b=
r><br></div></div></blockquote></span><div>Because of the wording. The type=
`any`, as the (most) general type-erased type, has nothing to do with copy=
able or not. But since you may want to allow passing it by value (as contai=
ners), it should at leas an object type.<br><br>Strictly speaking, even the=
"copy" itself has problem. A copy-constructible type is copy-ini=
tializable. A movable but not copy-constructible type is still copy-initial=
izable. Is the copyable type copy-initializable or copy-constructible? This=
was not a problem in C++98/03, but it is a problem here. Copy constructor =
of `any` forwards the work to the contained object. The strategy of copy (e=
ither deep, shallow, sharing, etc) is determined by the copy constructor of=
contained object. Having assumption of the behavior of the copy constructo=
r seems to be not so useful, compared with "where it can be used"=
, at least to people who wants to provide the type signature concerned with=
`any`.<br><br></div><span class=3D""><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div>=C2=A0<br></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"><div>Also, it should be noted that it wouldn't be dif=
ficult at all to create a template wrapper type for non-copyable types, whi=
ch will have a copy constructor but will throw if you try to use it. That w=
ould give you most of the effect you want.<br><br>You would need `make_nonc=
opyable_any<T>` to create such an `any` (if `T` is copyable, it won&#=
39;t wrap it). And you would need `noncopyable_any_cast<T>` to cast i=
t back (it would first try getting the wrapped `T`; if that failed, it woul=
d try to get `T` directly. That allow `T` to be copyable). Both of which ca=
n be written outside of the class.<br><br>So if you really, <i>truly</i> wa=
nt this... you can still do it with `any` as it currently stands.<br></div>=
<div><br></div></div></blockquote><div><br>Good workaround. But no, how to =
initialize the wrapper?</div></div></blockquote><div><br>Um... exactly like=
I said: `make_noncopyable_any`. This ain't rocket science here. <br></=
div></div></blockquote><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"><div></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div> What if an instance of `std::atomic`?</div></div></block=
quote><div><br>`any` can copy from a value or move from it. But it cannot t=
ake a value from a list of arguments and a type. You would need explicit em=
placement construction support to do that, something like what P0032 propos=
es.<br><br>But if you had that, then `make_noncopyable_any` would be able t=
o work with immobile types too. There's nothing in the wrapper that wou=
ld prevent that.<br><br></div></div></blockquote></span><div>That's als=
o a good idea. Note I also mentioned emplacement, before I realized there i=
s P0032.<br><br>P0135 mandates the copy elision. If it is approved, then mo=
st of these problem would not exist.<br>=C2=A0<br></div><span class=3D""><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Why bother more indire=
ct step to do the literally correct thing (to initialize "any" ob=
ject)?<br></div></div></blockquote><div><br>What you want is not "the =
literally correct thing" <i>just because you declare it so</i>.<br>=C2=
=A0</div></div></blockquote></span><div>Well, the type <i>`any` does not de=
clare it is copyable literally</i> <i>by its name</i>, isn't it true?<b=
r>=C2=A0<br></div><span class=3D""><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"><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"ltr">=
<div>If you think it is dangerous to allow noncopyable objects silently ini=
tialize the `any` object, that's fair. You want to differentiate them. =
OK. Let's have the compromise. Why should it be out of the interface of=
the class `any`? Can you have a constructor template with a special tag to=
indicate this use?</div></div></blockquote><div><br>That's not a "=
;compromise"; that's <i>surrender</i>.<br><br>A "compromise&q=
uot; is where you get some of what you want, and I get some of what I want.=
By putting the wrapper directly into the interface of `any`, you get <i>ev=
erything</i> you want, and I get <i>nothing</i> I want.<br><br></div></div>=
</blockquote></span><div><i>What </i>do you want to get? To not modify the =
working draft?<br><br>Besides the assumption in your mind, do you actually =
<i>rely on</i> that any will not throw during copying unless the contained =
object throws?<br><br>You can ignore what you does not need. Even if you wa=
nt the type checking for copy-constructible when the feature I want here ha=
s changed the behavior of the constructor template `any`, just use `static_=
assert`. By using additional tag type, it even does not force you to change=
your code since you never use it at all. You only need one more explicit n=
otice for your clients (and yourself): if someone dare make the copy of `an=
y` actually throwing, the behavior of the program is not guaranteed predict=
able. This<i> is </i>the status quo, <i>implicitly</i>.<br><br>This <i>is <=
/i>the compromise because it allows you to pretend the problem does not exi=
st - that <i>is</i> your gain in the case when the interface has changed an=
d it does not break your code or limit you to write anything. It <i>is </i>=
a surrender to keep `any` not changed for me, because <i>while the nominal =
interface is disputable</i>, I actually lose something just because someone=
else declared it is not cared and never used at all, and I eventually have=
to <i>reinvent wheels</i> and pay for what I will not used after that (e.g=
.. the binary size of dynamic library of the standard library implementation=
). Remember what the standard library is used for.<br>=C2=A0<br></div><span=
class=3D""><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"><div>R=
emember: by creating this wrapped `any` instance, you're introducing <i=
>fragility</i> into your codebase. It should be clear and obvious when you =
do this, and it should not look like normal creation of an `any` instance.<=
/div></div></blockquote></span><div><br>This is not like normally because o=
f your manner of creation, which is the result. Once `any` is not `any_copy=
able` and the implicit rules of "use copyable types" principle is=
not clarified by the standard clearly, this should be normal.<br>=C2=A0</d=
iv><span class=3D""><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>It should <i>not happen by accident</i>.<br><br></div></div></blockq=
uote></span><div>However, this is true, because any creation of `any` shoul=
d not be the most frequent operations within such a statically typed langua=
ge. So is `void*`. And I don't think I should only be able to do that w=
ith an indirect layer to emphasize it in a strange, nonstandard way. <br></=
div><span class=3D""><div>=C2=A0<br></div><blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>What I suggested is a compromise. My position =
is that nobody should be able to create an `any` instance which will always=
throw on copy. Your position is that `any` should be able to accept non-co=
pyable or immobile types. The compromise is that, by default you can't =
use non-copyable types. But you can use a wrapper to use non-copyable types=
, and there's nothing I can do to stop you.<br>=C2=A0</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"><div>Even not, should the wrap=
per be standardized?<br></div></div></blockquote><div><br>Probably not. The=
re would be some advantage to it; it would be more searchable, since everyo=
ne would not have different implementations.</div></div></blockquote></span=
><div>My main point is to avoid to reinvent wheels for basic need that is e=
asily to met when not deliberately neglected. Though I agree with advantage=
of searching.<br>=C2=A0<br></div><span class=3D""><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>But putting it in the standard also m=
akes people think that using them is a good idea.<br><br></div></div></bloc=
kquote></span><div>No. Putting in the standard does not necessarily encoura=
ge using for anyone, it may also just because:<br><br>- Being necessary to =
support the language implementation.<br>- To keep compatibility with the cu=
rrent practice.<br>- The non portable replacements can not work well in nea=
r future.<br>- To avoid too many wheels to be invented.<br><br>Not all of t=
he reasons have the same effect to any interface.<br><br>People should have=
learned that they should use what they need.<br>=C2=A0<br></div><span clas=
s=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>However, no o=
ne was taught "any" should be copyable. <br></div></div></blockqu=
ote><div><br>You mean besides everyone who has used `boost::any` for over a=
decade?<br></div></div></blockquote></span><div><br>I don't use `boost=
::any` even if I would copy some reasonable design from that (e.g. some nam=
es of member). That is trivial. I don't complain about `boost::any` her=
e, because it is prefixed with `boost::`, which indicates it has no power t=
o define <i>what </i>is C++, which is not I cared here. I can ignore that d=
esign if I do not think it is good enough.<br><br>But all C++ users should =
face the standard, directly or indirectly, or they were not learning C++, b=
ut a flavored dialect. Once an interface fixed in the standard, the future =
change would cost probably much, not only in the language, but also for imp=
lementations and mind of users.<br><br></div><span class=3D""><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div> That's also why someon=
e will be surprised.<br></div></div></blockquote><div><br>I don't care.=
<br><br></div></div></blockquote></span><div>And you still cannot persuade =
me that the current design <i>has done the right thing</i> undoubtfully, th=
at means you can't assert a change will not be considerable. Before you=
have proven anyone should not care it, it deserves.<br>=C2=A0<br></div><sp=
an class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Also, do you =
really want to argue "possible misconception to new users"? Don&#=
39;t you think users will find it far more surprising that a type that is s=
upposedly copyable will emit an exception on copy for seemingly no reason? =
Not to mention that such surprises will be <i>runtime errors</i>, rather th=
an compile-time failures...<br><br></div></div></blockquote><div>They shoul=
d not be so surprised if they know what type erasure stands for.<br></div><=
/div></blockquote><div><br>... what? The concept of type erasure has nothin=
g at all to do with the behavior of a value type or reference type. You can=
make a type-erased copyable value type (aka: `any`). You can make a type-e=
rased moveable value type (`unique_any`). You can make a type-erased non-ow=
ning reference type. You can make a type-erased owning reference type (`sha=
red_any`). And so forth.<br><br>The concept of type erasure does not in any=
way conflict with the concept of copying. So knowing about type erasure do=
es not in any way require you to believe that a type-erased type would not =
be copyable. Again, see `std::function`.</div></div></blockquote></span><di=
v>It should not depend on copying, either. It should be the representative =
of type-erased because of its naming, but why with unrelated limitations?<b=
r>Function does not matter much because it is "function", not &qu=
ot;any". Though `std::function` is still not enough in practice, but i=
t is another topic.<br>=C2=A0<br></div></div><span class=3D"">
<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/be43d58f-39c5-4315-bba2-de9ec9e6aa96%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/be43d58f-39c5-=
4315-bba2-de9ec9e6aa96%40isocpp.org</a>.<br>
</blockquote></div><br></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/CADbh%2BeQYGdYQy1Uacx8z%2BUcC4kBJq3ic=
B7ZsqZOH_kbYy0TZXA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeQYGd=
YQy1Uacx8z%2BUcC4kBJq3icB7ZsqZOH_kbYy0TZXA%40mail.gmail.com</a>.<br />
--001a114b1588fe3106053196d440--
.
Author: FrankHB1989 <frankhb1989@gmail.com>
Date: Thu, 28 Apr 2016 23:55:39 -0700 (PDT)
Raw View
------=_Part_6655_276136394.1461912939853
Content-Type: multipart/alternative;
boundary="----=_Part_6656_1898852002.1461912939854"
------=_Part_6656_1898852002.1461912939854
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E5=9C=A8 2016=E5=B9=B44=E6=9C=8829=E6=97=A5=E6=98=9F=E6=9C=9F=E4=BA=94 UTC=
+8=E4=B8=8A=E5=8D=8810:59:34=EF=BC=8CBrent Friedman=E5=86=99=E9=81=93=EF=BC=
=9A
>
> I think it will be useful to allow noncopyable values in the constructor=
=20
>> template
>
>
> This is a long thread, but I don't think the following solution has been=
=20
> considered. It transforms noncopyable types to copyable types by throwing=
..=20
> It seems like it resolves the issue without changes to any. I think it=20
> should allow you to use noncopyable types with all containers as long as=
=20
> the containers provide the necessary exception guarantees. What do you=20
> think?
>
> struct noncopyable_exception {};
>
> template<class T>
> struct throw_on_copy
> {
> T data;
> template<class... Args>
> throw_on_copy(Args... args)
> :data(std::forward<Args>(args)...)
> {
> }
> throw_on_copy(const throw_on_copy&)
> {
> throw noncopyable_exception{};
> }
> throw_on_copy(throw_on_copy&&)=3Ddefault;
>
> throw_on_copy& operator=3D(const throw_on_copy&)
> {
> throw noncopyable_exception{};
> }
> throw_on_copy& operator=3D(throw_on_copy&&) =3D default;
> };
>
> std::any v{ throw_on_copy<my_noncopyable_type>{arg0,arg1,arg2} };
>
>
> The wrapper approach has been discussed. It can resolve some problems but=
=20
it is still problematic.=20
>
> On Thu, Apr 28, 2016 at 5:29 AM, FrankHB1989 <frank...@gmail.com=20
> <javascript:>> wrote:
>
>>
>>
>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8827=E6=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 =
UTC+8=E4=B8=8A=E5=8D=882:12:00=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=
=9A
>>>
>>> On Monday, April 25, 2016 at 7:29:07 AM UTC-4, FrankHB1989 wrote:
>>>>
>>>> =E5=9C=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=
=A5 UTC+8=E4=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=
=EF=BC=9A
>>>>>
>>>>> How exactly does that cause a performance regression? The alternative=
=20
>>>>> to `any` is a `void*`. Which requires heap allocation (or keeping aro=
und a=20
>>>>> pointer to a stack or global object). `void*` is not a value-type, so=
it's=20
>>>>> impossible to copy it.
>>>>>
>>>>> If you change your code from using `void*` to `any`, you would have n=
o=20
>>>>> reason to suddenly decide to start copying `any` objects. Since that'=
s an=20
>>>>> operation that wasn't available before. So in both cases, the big obj=
ect=20
>>>>> was heap allocated and in both cases, the object was not copied.
>>>>>
>>>>> So where is the "performance regression"?
>>>>>
>>>>> You would only get a "performance regression" if you completely=20
>>>>> changed the nature of the code. And that would only happen if you are=
n't=20
>>>>> paying attention to what you're doing.
>>>>>
>>>>> Quite frankly, if you're not paying attention to what you're doing in=
=20
>>>>> C++, you shouldn't be using the language.
>>>>>
>>>>> You did not get the point.
>>>>
>>>> It is a side effect *after replacing a concrete type with `any`*.
>>>>
>>>
>>> Stop. Why would you ever be doing that?
>>>
>> The similar reason to turning a concrete type to `void*`.=20
>>
>>>
>>> `any` is a type-safe replacement for `void*`, not "a concrete type". So=
=20
>>> what is your code doing where you uses to take a specific type, and now=
you=20
>>> have decided to take anything? Especially when you were presumably taki=
ng=20
>>> that type as a by-value parameter (more on that later).
>>>
>>> But `void*` does not have the problem.
>>
>> It seems to me that the type you would be interested in is `variant`.
>>>
>>> Yes I also need it, but it's elsewhere. I clearly know they are=20
>> different.
>>
>> And actually I need `any` does not only to replace `void*`. An object ca=
n=20
>> have side effect in its destruction in a polymorphic way, which is not=
=20
>> possible for `void*`.
>>
>> Because `any` allows any "copy" occurs in its copy constructor literally=
,=20
>>>> it is difficult to evaluate what the performance penalty it would be,=
=20
>>>> particularly when the contained object is provided by the client code.=
=20
>>>> Because `any` does not limit it at all, users may easily do things you=
=20
>>>> don't want, unless warned seriously (by some means not part of C++).
>>>>
>>>
>>> ... maybe you haven't gotten the point yet, but *I don't care*.
>>>
>>> Whether you care or not, that problem may likely occur. I'm still not=
=20
>> sure how your point can work around it.
>>
>> My point here is that `any` does not fit for the work very well. If you=
=20
>> are forced to use `any` in such a manner without control, something has=
=20
>> already gone wrong. And you have to ignore this problem, if you insist o=
n=20
>> using `any` here anyway.
>> =20
>>
>>> The fact that someone, somewhere, can misuse something to their=20
>>> performance detriment is not by itself sufficient reason to disallow it=
..=20
>>> `unique_ptr` disallows copying because it conceptually makes no sense t=
o=20
>>> copy something which is uniquely owned by this object. It's a logical=
=20
>>> contradiction and therefore disallowed.
>>>
>>> That's not the case with `any`.
>>>
>>> Yes. Allowing copy is the nature of `any` (at least in the current=20
>> design). But this does not mean it is *suitable *to be copied in general=
..
>> =20
>>
>>> Is this the mistake of users? Partially, but not all. The design here i=
s=20
>>>> essentially doubtful. Usually, you would care about copy of containers=
so=20
>>>> you should not pass the container by value. However, you seem to tend =
to a=20
>>>> similar but worse choice for `any` here. Why?
>>>>
>>>> The fact is, `any` cannot be used as a passed-by-value parameter type=
=20
>>>> that easily.
>>>>
>>>
>>> So what? Why are you so focused on using `any` as a "by-value=20
>>> parameter"? Nobody is suggesting that people should start writing APIs =
that=20
>>> take `any` instances as "by-value parameters". You are complaining abou=
t=20
>>> people doing something that nobody actually wants to do.
>>>
>>> Well, nobody except maybe you.
>>>
>>> Huh? Then what you were arguing about? If you don't use `any` by-value,=
=20
>> when will you copy it (frequently)?
>> =20
>>
>>> Do we tell people to take `vector` by value parameter? `optional`?=20
>>> `variant`? `std::function`? No. We generally tell people to take such t=
ypes=20
>>> by reference.
>>>
>> By taking reference, object of `any` is not copied.=20
>>
>>> =20
>>>
>>>> Such use need extraordinary care, within limited use cases.
>>>>
>>>
>>> Using a `const any&` is not "extraordinary care". Nor does it limit use=
=20
>>> cases.
>>> =20
>>>
>> Sure. That was about `any` passed by-value.
>> =20
>>
>>> Nevertheless, the use of being passed by value is not the killer featur=
e=20
>>>>>> of `any` at first. To use it as a data member has no such problems.
>>>>>>
>>>>>
>>>>> It becomes a problem if it's a data member of a copyable type.
>>>>>
>>>> If you want the enclosing class to be copyable, either limit access of=
=20
>>>> this data member, or do not use the enclosing class as a function para=
meter=20
>>>> at all.
>>>>
>>>
>>> Again with the "function parameter" stuff. You act like being a by-valu=
e=20
>>> parameter is the end-all-be-all of types.
>>>
>>> It isn't.
>>>
>>> So why are you so interested in limiting the uniform behavior of=20
>> copying? If it is not used at implicit copy-initialization (mainly=20
>> passing-by-value cases), is it still error-prone?
>> =20
>>
>>> Whether a type is copyable or not has *nothing* to do with whether you=
=20
>>> should use it as a by-value parameter or not. `vector` is copyable, but=
=20
>>> that doesn't mean you should copy it a lot.
>>>
>>
>> I have already mentioned this.
>>
>> If you agree that is comparable, why not force element of `vector`=20
>> copyable? Just because the *implementation details* of type erasure need=
=20
>> it to live or die in the whole type level for `any` while not for `vecto=
r`?
>>
>> =20
>>>
>>>> Not every type can be used by every person. No type fits every need.=
=20
>>>>> I'm sure people would really like to be able to store non-copyable fu=
nctors=20
>>>>> in `std::function` too.
>>>>> =20
>>>>>
>>>> I know I would.
>>>>>
>>>>> But that doesn't mean that `std::function` is the type that should=20
>>>>> allow that.
>>>>>
>>>>> A non-copyable function is not a traditional "function" (decayed as a=
=20
>>>> function pointer). But the meaning of "any" diverges.
>>>>
>>>
>>> Yes, `any` diverges from `void*`. That's because `any` is designed to b=
e=20
>>> a *safe* `void*`. It achieves this in two ways:
>>>
>>> 1. Casting is type-checked and will fail if the user does not supply th=
e=20
>>> actual type used to create the `any`.
>>>
>>> 2. The value stored is *owned* by the `any`, thus preventing any chance=
=20
>>> of the object no longer being valid by the time it is recovered.
>>>
>>> If you want to believe that people will expect `any` to provide #1=20
>>> without #2, go ahead.
>>> =20
>>>
>> True. But is this relevant to being copyable?
>> =20
>>
>>> Having a class change its behavior in such a fundamental way, based=20
>>>>> solely on how it was initialized, is not a "clean" method of coding. =
It=20
>>>>> makes it very difficult to look at a piece of code and statically kno=
w if=20
>>>>> it is reasonable.
>>>>>
>>>>>
>>>> For the case of `any`, it is already not so clean. It is the=20
>>>> half-measure to grant false assumption about behavior of copy construc=
tion=20
>>>> to users, since the precise behavior may be not measurable at all - it=
can=20
>>>> be anything out of your control. Both disallowing copying totally and=
=20
>>>> allowing copying + moving are more natural.
>>>>
>>>> Because it is named `any`, not `any_copyable`, it gives users extra=20
>>>> surprise.
>>>>
>>>
>>> That assumes the user would expect `any` (or any C++ type) to not be=20
>>> copyable. I fail to see how that's a valid assumption, considering that=
=20
>>> most C++ standard library types are copyable.
>>>
>>> Because of the wording. The type `any`, as the (most) general=20
>> type-erased type, has nothing to do with copyable or not. But since you =
may=20
>> want to allow passing it by value (as containers), it should at leas an=
=20
>> object type.
>>
>> Strictly speaking, even the "copy" itself has problem. A=20
>> copy-constructible type is copy-initializable. A movable but not=20
>> copy-constructible type is still copy-initializable. Is the copyable typ=
e=20
>> copy-initializable or copy-constructible? This was not a problem in=20
>> C++98/03, but it is a problem here. Copy constructor of `any` forwards t=
he=20
>> work to the contained object. The strategy of copy (either deep, shallow=
,=20
>> sharing, etc) is determined by the copy constructor of contained object.=
=20
>> Having assumption of the behavior of the copy constructor seems to be no=
t=20
>> so useful, compared with "where it can be used", at least to people who=
=20
>> wants to provide the type signature concerned with `any`.
>>
>> =20
>>>>
>>>>> Also, it should be noted that it wouldn't be difficult at all to=20
>>>>> create a template wrapper type for non-copyable types, which will hav=
e a=20
>>>>> copy constructor but will throw if you try to use it. That would give=
you=20
>>>>> most of the effect you want.
>>>>>
>>>>> You would need `make_noncopyable_any<T>` to create such an `any` (if=
=20
>>>>> `T` is copyable, it won't wrap it). And you would need=20
>>>>> `noncopyable_any_cast<T>` to cast it back (it would first try getting=
the=20
>>>>> wrapped `T`; if that failed, it would try to get `T` directly. That a=
llow=20
>>>>> `T` to be copyable). Both of which can be written outside of the clas=
s.
>>>>>
>>>>> So if you really, *truly* want this... you can still do it with `any`=
=20
>>>>> as it currently stands.
>>>>>
>>>>>
>>>> Good workaround. But no, how to initialize the wrapper?
>>>>
>>>
>>> Um... exactly like I said: `make_noncopyable_any`. This ain't rocket=20
>>> science here.=20
>>>
>>
>>> What if an instance of `std::atomic`?
>>>>
>>>
>>> `any` can copy from a value or move from it. But it cannot take a value=
=20
>>> from a list of arguments and a type. You would need explicit emplacemen=
t=20
>>> construction support to do that, something like what P0032 proposes.
>>>
>>> But if you had that, then `make_noncopyable_any` would be able to work=
=20
>>> with immobile types too. There's nothing in the wrapper that would prev=
ent=20
>>> that.
>>>
>>> That's also a good idea. Note I also mentioned emplacement, before I=20
>> realized there is P0032.
>>
>> P0135 mandates the copy elision. If it is approved, then most of these=
=20
>> problem would not exist.
>> =20
>>
>>> Why bother more indirect step to do the literally correct thing (to=20
>>>> initialize "any" object)?
>>>>
>>>
>>> What you want is not "the literally correct thing" *just because you=20
>>> declare it so*.
>>> =20
>>>
>> Well, the type *`any` does not declare it is copyable literally* *by its=
=20
>> name*, isn't it true?
>> =20
>>
>>> If you think it is dangerous to allow noncopyable objects silently=20
>>>> initialize the `any` object, that's fair. You want to differentiate th=
em.=20
>>>> OK. Let's have the compromise. Why should it be out of the interface o=
f the=20
>>>> class `any`? Can you have a constructor template with a special tag to=
=20
>>>> indicate this use?
>>>>
>>>
>>> That's not a "compromise"; that's *surrender*.
>>>
>>> A "compromise" is where you get some of what you want, and I get some o=
f=20
>>> what I want. By putting the wrapper directly into the interface of `any=
`,=20
>>> you get *everything* you want, and I get *nothing* I want.
>>>
>>> *What *do you want to get? To not modify the working draft?
>>
>> Besides the assumption in your mind, do you actually *rely on* that any=
=20
>> will not throw during copying unless the contained object throws?
>>
>> You can ignore what you does not need. Even if you want the type checkin=
g=20
>> for copy-constructible when the feature I want here has changed the=20
>> behavior of the constructor template `any`, just use `static_assert`. By=
=20
>> using additional tag type, it even does not force you to change your cod=
e=20
>> since you never use it at all. You only need one more explicit notice fo=
r=20
>> your clients (and yourself): if someone dare make the copy of `any`=20
>> actually throwing, the behavior of the program is not guaranteed=20
>> predictable. This* is *the status quo, *implicitly*.
>>
>> This *is *the compromise because it allows you to pretend the problem=20
>> does not exist - that *is* your gain in the case when the interface has=
=20
>> changed and it does not break your code or limit you to write anything. =
It *is=20
>> *a surrender to keep `any` not changed for me, because *while the=20
>> nominal interface is disputable*, I actually lose something just because=
=20
>> someone else declared it is not cared and never used at all, and I=20
>> eventually have to *reinvent wheels* and pay for what I will not used=20
>> after that (e.g. the binary size of dynamic library of the standard libr=
ary=20
>> implementation). Remember what the standard library is used for.
>> =20
>>
>>> Remember: by creating this wrapped `any` instance, you're introducing=
=20
>>> *fragility* into your codebase. It should be clear and obvious when you=
=20
>>> do this, and it should not look like normal creation of an `any` instan=
ce.
>>>
>>
>> This is not like normally because of your manner of creation, which is=
=20
>> the result. Once `any` is not `any_copyable` and the implicit rules of "=
use=20
>> copyable types" principle is not clarified by the standard clearly, this=
=20
>> should be normal.
>> =20
>>
>>> It should *not happen by accident*.
>>>
>>> However, this is true, because any creation of `any` should not be the=
=20
>> most frequent operations within such a statically typed language. So is=
=20
>> `void*`. And I don't think I should only be able to do that with an=20
>> indirect layer to emphasize it in a strange, nonstandard way.=20
>> =20
>>
>>> What I suggested is a compromise. My position is that nobody should be=
=20
>>> able to create an `any` instance which will always throw on copy. Your=
=20
>>> position is that `any` should be able to accept non-copyable or immobil=
e=20
>>> types. The compromise is that, by default you can't use non-copyable ty=
pes.=20
>>> But you can use a wrapper to use non-copyable types, and there's nothin=
g I=20
>>> can do to stop you.
>>> =20
>>>
>>>> Even not, should the wrapper be standardized?
>>>>
>>>
>>> Probably not. There would be some advantage to it; it would be more=20
>>> searchable, since everyone would not have different implementations.
>>>
>> My main point is to avoid to reinvent wheels for basic need that is=20
>> easily to met when not deliberately neglected. Though I agree with=20
>> advantage of searching.
>> =20
>>
>>> But putting it in the standard also makes people think that using them=
=20
>>> is a good idea.
>>>
>>> No. Putting in the standard does not necessarily encourage using for=20
>> anyone, it may also just because:
>>
>> - Being necessary to support the language implementation.
>> - To keep compatibility with the current practice.
>> - The non portable replacements can not work well in near future.
>> - To avoid too many wheels to be invented.
>>
>> Not all of the reasons have the same effect to any interface.
>>
>> People should have learned that they should use what they need.
>> =20
>>
>>> However, no one was taught "any" should be copyable.=20
>>>>
>>>
>>> You mean besides everyone who has used `boost::any` for over a decade?
>>>
>>
>> I don't use `boost::any` even if I would copy some reasonable design fro=
m=20
>> that (e.g. some names of member). That is trivial. I don't complain abou=
t=20
>> `boost::any` here, because it is prefixed with `boost::`, which indicate=
s=20
>> it has no power to define *what *is C++, which is not I cared here. I=20
>> can ignore that design if I do not think it is good enough.
>>
>> But all C++ users should face the standard, directly or indirectly, or=
=20
>> they were not learning C++, but a flavored dialect. Once an interface fi=
xed=20
>> in the standard, the future change would cost probably much, not only in=
=20
>> the language, but also for implementations and mind of users.
>>
>> =20
>>>
>>>> That's also why someone will be surprised.
>>>>
>>>
>>> I don't care.
>>>
>>> And you still cannot persuade me that the current design *has done the=
=20
>> right thing* undoubtfully, that means you can't assert a change will not=
=20
>> be considerable. Before you have proven anyone should not care it, it=20
>> deserves.
>> =20
>>
>>> Also, do you really want to argue "possible misconception to new users"=
?=20
>>>>> Don't you think users will find it far more surprising that a type th=
at is=20
>>>>> supposedly copyable will emit an exception on copy for seemingly no r=
eason?=20
>>>>> Not to mention that such surprises will be *runtime errors*, rather=
=20
>>>>> than compile-time failures...
>>>>>
>>>>> They should not be so surprised if they know what type erasure stands=
=20
>>>> for.
>>>>
>>>
>>> ... what? The concept of type erasure has nothing at all to do with the=
=20
>>> behavior of a value type or reference type. You can make a type-erased=
=20
>>> copyable value type (aka: `any`). You can make a type-erased moveable v=
alue=20
>>> type (`unique_any`). You can make a type-erased non-owning reference ty=
pe.=20
>>> You can make a type-erased owning reference type (`shared_any`). And so=
=20
>>> forth.
>>>
>>> The concept of type erasure does not in any way conflict with the=20
>>> concept of copying. So knowing about type erasure does not in any way=
=20
>>> require you to believe that a type-erased type would not be copyable.=
=20
>>> Again, see `std::function`.
>>>
>> It should not depend on copying, either. It should be the representative=
=20
>> of type-erased because of its naming, but why with unrelated limitations=
?
>> Function does not matter much because it is "function", not "any". Thoug=
h=20
>> `std::function` is still not enough in practice, but it is another topic=
..
>> =20
>>
>> --=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit=20
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/be43d58f-39=
c5-4315-bba2-de9ec9e6aa96%40isocpp.org=20
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/be43d58f-3=
9c5-4315-bba2-de9ec9e6aa96%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoo=
ter>
>> .
>>
>
>
--=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/92c6463b-dc6d-4b4d-84c2-b421be98d3a4%40isocpp.or=
g.
------=_Part_6656_1898852002.1461912939854
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8829=E6=97=A5=E6=98=
=9F=E6=9C=9F=E4=BA=94 UTC+8=E4=B8=8A=E5=8D=8810:59:34=EF=BC=8CBrent Friedma=
n=E5=86=99=E9=81=93=EF=BC=9A<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-lef=
t-style:solid;padding-left:1ex"><span style=3D"font-size:12.8px">I think it=
will be useful to allow noncopyable values in the constructor template</sp=
an></blockquote><div><br></div><div>This is a long thread, but I don't =
think the following solution has been considered. It transforms noncopyable=
types to copyable types by throwing. It seems like it resolves the issue w=
ithout changes to any. I think it should allow you to use noncopyable types=
with all containers as long as the containers provide the necessary except=
ion guarantees. What do you think?</div><div><br></div><blockquote style=3D=
"margin:0 0 0 40px;border:none;padding:0px"><div><div>struct noncopyable_ex=
ception {};</div></div><div><div><br></div></div><div><div>template<clas=
s T></div></div><div><div>struct throw_on_copy</div></div><div><div>{</d=
iv></div><div><div><span style=3D"white-space:pre"> </span>T data;</div></d=
iv><div><div><span style=3D"white-space:pre"> </span>template<class... A=
rgs></div></div><div><div><span style=3D"white-space:pre"> </span>throw_=
on_copy(Args... args)</div></div><div><div><span style=3D"white-space:pre">=
</span>:data(std::forward<Args>(args)<wbr>...)</div></div><div><div=
><span style=3D"white-space:pre"> </span>{</div></div><div><div><span style=
=3D"white-space:pre"> </span>}</div></div><div><div><span style=3D"white-sp=
ace:pre"> </span>throw_on_copy(const throw_on_copy&)</div></div><div><d=
iv><span style=3D"white-space:pre"> </span>{</div></div><div><div><span sty=
le=3D"white-space:pre"> </span>throw noncopyable_exception{};</div></div><=
div><div><span style=3D"white-space:pre"> </span>}</div></div><div><div><sp=
an style=3D"white-space:pre"> </span>throw_on_copy(throw_on_copy&&)=
<wbr>=3Ddefault;</div></div><div><div><br></div></div><div><div><span style=
=3D"white-space:pre"> </span>throw_on_copy& operator=3D(const throw_on_=
copy&)</div></div><div><div><span style=3D"white-space:pre"> </span>{</=
div></div><div><div><span style=3D"white-space:pre"> </span>throw noncopya=
ble_exception{};</div></div><div><div><span style=3D"white-space:pre"> </sp=
an>}</div></div><div><div><span style=3D"white-space:pre"> </span>throw_on_=
copy& operator=3D(throw_on_copy&&) =3D default;</div></div><div=
><div>};</div></div><div><br></div><div>std::any v{ throw_on_copy<my_non=
copyable_<wbr>type>{arg0,arg1,arg2} };</div></blockquote><div><br></div>=
</div></blockquote><div>The wrapper approach has been discussed. It can res=
olve some problems but it is still problematic. <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div></div><div><br><div=
class=3D"gmail_quote">On Thu, Apr 28, 2016 at 5:29 AM, FrankHB1989 <span d=
ir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mai=
lto=3D"21hSTDlzBAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javas=
cript:';return true;" onclick=3D"this.href=3D'javascript:';retu=
rn true;">frank...@gmail.com</a>></span> wrote:<br><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><br><br>=E5=9C=A8 2016=E5=B9=B44=E6=9C=8827=E6=
=97=A5=E6=98=9F=E6=9C=9F=E4=B8=89 UTC+8=E4=B8=8A=E5=8D=882:12:00=EF=BC=8CNi=
col Bolas=E5=86=99=E9=81=93=EF=BC=9A<span><blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr">On Monday, April 25, 2016 at 7:29:07 AM UTC-4, Fran=
kHB1989 wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=E5=
=9C=A8 2016=E5=B9=B44=E6=9C=8824=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5 UTC+8=
=E4=B8=8A=E5=8D=8811:36:19=EF=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>How exactly doe=
s that cause a performance regression? The alternative to `any` is a `void*=
`. Which requires heap allocation (or keeping around a pointer to a stack o=
r global object). `void*` is not a value-type, so it's impossible to co=
py it.<br><br>If you change your code from using `void*` to `any`, you woul=
d have no reason to suddenly decide to start copying `any` objects. Since t=
hat's an operation that wasn't available before. So in both cases, =
the big object was heap allocated and in both cases, the object was not cop=
ied.<br><br>So where is the "performance regression"?<br><br>You =
would only get a "performance regression" if you completely chang=
ed the nature of the code. And that would only happen if you aren't pay=
ing attention to what you're doing.<br><br>Quite frankly, if you're=
not paying attention to what you're doing in C++, you shouldn't be=
using the language.<br><br></div></div></blockquote><div>You did not get t=
he point.<br><br>It is a side effect <i>after replacing a concrete type wit=
h `any`</i>.</div></div></blockquote><div><br>Stop. Why would you ever be d=
oing that?<br></div></div></blockquote></span><div>The similar reason to tu=
rning a concrete type to `void*`. <br></div><span><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div><br>`any` is a type-safe replacement f=
or `void*`, not "a concrete type". So what is your code doing whe=
re you uses to take a specific type, and now you have decided to take anyth=
ing? Especially when you were presumably taking that type as a by-value par=
ameter (more on that later).<br><br></div></div></blockquote></span><div>Bu=
t `void*` does not have the problem.<br><br></div><span><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>It seems to me that the type y=
ou would be interested in is `variant`.<br><br></div></div></blockquote></s=
pan><div>Yes I also need it, but it's elsewhere. I clearly know they ar=
e different.<br><br>And actually I need `any` does not only to replace `voi=
d*`. An object can have side effect in its destruction in a polymorphic way=
, which is not possible for `void*`.<br><br></div><span><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>Because `any` allows any "copy&q=
uot; occurs in its copy constructor literally, it is difficult to evaluate =
what the performance penalty it would be, particularly when the contained o=
bject is provided by the client code. Because `any` does not limit it at al=
l, users may easily do things you don't want, unless warned seriously (=
by some means not part of C++).<br></div></div></blockquote><div><br>... ma=
ybe you haven't gotten the point yet, but <i>I don't care</i>.<br><=
br></div></div></blockquote></span><div>Whether you care or not, that probl=
em may likely occur. I'm still not sure how your point can work around =
it.<br><br>My point here is that `any` does not fit for the work very well.=
If you are forced to use `any` in such a manner without control, something=
has already gone wrong. And you have to ignore this problem, if you insist=
on using `any` here anyway.<br>=C2=A0<br></div><span><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"><div>The fact that someone, somewhere, =
can misuse something to their performance detriment is not by itself suffic=
ient reason to disallow it. `unique_ptr` disallows copying because it conce=
ptually makes no sense to copy something which is uniquely owned by this ob=
ject. It's a logical contradiction and therefore disallowed.<br><br>Tha=
t's not the case with `any`.<br><br></div></div></blockquote></span><di=
v>Yes. Allowing copy is the nature of `any` (at least in the current design=
). But this does not mean it is <i>suitable </i>to be copied in general.<br=
>=C2=A0<br></div><span><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"><div></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"><d=
iv>Is this the mistake of users? Partially, but not all. The design here is=
essentially doubtful. Usually, you would care about copy of containers so =
you should not pass the container by value. However, you seem to tend to a =
similar but worse choice for `any` here. Why?<br><br>The fact is, `any` can=
not be used as a passed-by-value parameter type that easily.</div></div></b=
lockquote><div><br>So what? Why are you so focused on using `any` as a &quo=
t;by-value parameter"? Nobody is suggesting that people should start w=
riting APIs that take `any` instances as "by-value parameters". Y=
ou are complaining about people doing something that nobody actually wants =
to do.<br><br>Well, nobody except maybe you.<br><br></div></div></blockquot=
e></span><div>Huh? Then what you were arguing about? If you don't use `=
any` by-value, when will you copy it (frequently)?<br>=C2=A0<br></div><span=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Do we tell p=
eople to take `vector` by value parameter? `optional`? `variant`? `std::fun=
ction`? No. We generally tell people to take such types by reference.<br></=
div></div></blockquote></span><div>By taking reference, object of `any` is =
not copied. <br></div><span><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div> Such use need extraordinary care, within limited use cases.=
</div></div></blockquote><div><br>Using a `const any&` is not "ext=
raordinary care". Nor does it limit use cases.<br>=C2=A0</div></div></=
blockquote></span><div>Sure. That was about `any` passed by-value.<br>=C2=
=A0<br></div><span><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div></div></blockquote><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div>Nevertheless, the use of being passed by value i=
s not the killer feature of `any` at first. To use it as a data member has =
no such problems.</div></div></blockquote><div><br>It becomes a problem if =
it's a data member of a copyable type.<br></div></div></blockquote><div=
>If you want the enclosing class to be copyable, either limit access of thi=
s data member, or do not use the enclosing class as a function parameter at=
all.<br></div></div></blockquote><div><br>Again with the "function pa=
rameter" stuff. You act like being a by-value parameter is the end-all=
-be-all of types.<br><br>It isn't.<br><br></div></div></blockquote></sp=
an><div>So why are you so interested in limiting the uniform behavior of co=
pying? If it is not used at implicit copy-initialization (mainly passing-by=
-value cases), is it still error-prone?<br>=C2=A0<br></div><span><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Whether a type is copya=
ble or not has <i>nothing</i> to do with whether you should use it as a by-=
value parameter or not. `vector` is copyable, but that doesn't mean you=
should copy it a lot.<br></div></div></blockquote></span><div><br>I have a=
lready mentioned this.<br><br>If you agree that is comparable, why not forc=
e element of `vector` copyable? Just because the <i>implementation details<=
/i> of type erasure need it to live or die in the whole type level for `any=
` while not for `vector`?<br><br></div><span><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div></div><div></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div></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"><div></div></div></blockquote><div>Not every type ca=
n be used by every person. No type fits every need. I'm sure people wou=
ld really like to be able to store non-copyable functors in `std::function`=
too.<br>=C2=A0<br></div></div></blockquote><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>I know I would.<br><br>But that doesn't =
mean that `std::function` is the type that should allow that.<br><br></div>=
</div></blockquote><div>A non-copyable function is not a traditional "=
function" (decayed as a function pointer). But the meaning of "an=
y" diverges.<br></div></div></blockquote><div><br>Yes, `any` diverges =
from `void*`. That's because `any` is designed to be a <i>safe</i> `voi=
d*`. It achieves this in two ways:<br><br>1. Casting is type-checked and wi=
ll fail if the user does not supply the actual type used to create the `any=
`.<br><br>2. The value stored is <i>owned</i> by the `any`, thus preventing=
any chance of the object no longer being valid by the time it is recovered=
..<br><br>If you want to believe that people will expect `any` to provide #1=
without #2, go ahead.<br>=C2=A0</div></div></blockquote></span><div>True. =
But is this relevant to being copyable?<br>=C2=A0<br></div><span><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv></div></blockquote></div></blockquote><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"><div>Having a class change its behavior in such a fu=
ndamental way, based solely on how it was initialized, is not a "clean=
" method of coding. It makes it very difficult to look at a piece of c=
ode and statically know if it is reasonable.<br><br></div></div></blockquot=
e><div><br>For the case of `any`, it is already not so clean. It is the hal=
f-measure to grant false assumption about behavior of copy construction to =
users, since the precise behavior may be not measurable at all - it can be =
anything out of your control. Both disallowing copying totally and allowing=
copying + moving are more natural.<br><br>Because it is named `any`, not `=
any_copyable`, it gives users extra surprise.<br></div></div></blockquote><=
div><br>That assumes the user would expect `any` (or any C++ type) to not b=
e copyable. I fail to see how that's a valid assumption, considering th=
at most C++ standard library types are copyable.<br><br></div></div></block=
quote></span><div>Because of the wording. The type `any`, as the (most) gen=
eral type-erased type, has nothing to do with copyable or not. But since yo=
u may want to allow passing it by value (as containers), it should at leas =
an object type.<br><br>Strictly speaking, even the "copy" itself =
has problem. A copy-constructible type is copy-initializable. A movable but=
not copy-constructible type is still copy-initializable. Is the copyable t=
ype copy-initializable or copy-constructible? This was not a problem in C++=
98/03, but it is a problem here. Copy constructor of `any` forwards the wor=
k to the contained object. The strategy of copy (either deep, shallow, shar=
ing, etc) is determined by the copy constructor of contained object. Having=
assumption of the behavior of the copy constructor seems to be not so usef=
ul, compared with "where it can be used", at least to people who =
wants to provide the type signature concerned with `any`.<br><br></div><spa=
n><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0<br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Also, it should=
be noted that it wouldn't be difficult at all to create a template wra=
pper type for non-copyable types, which will have a copy constructor but wi=
ll throw if you try to use it. That would give you most of the effect you w=
ant.<br><br>You would need `make_noncopyable_any<T>` to create such a=
n `any` (if `T` is copyable, it won't wrap it). And you would need `non=
copyable_any_cast<T>` to cast it back (it would first try getting the=
wrapped `T`; if that failed, it would try to get `T` directly. That allow =
`T` to be copyable). Both of which can be written outside of the class.<br>=
<br>So if you really, <i>truly</i> want this... you can still do it with `a=
ny` as it currently stands.<br></div><div><br></div></div></blockquote><div=
><br>Good workaround. But no, how to initialize the wrapper?</div></div></b=
lockquote><div><br>Um... exactly like I said: `make_noncopyable_any`. This =
ain't rocket science here. <br></div></div></blockquote><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div> What if an instance=
of `std::atomic`?</div></div></blockquote><div><br>`any` can copy from a v=
alue or move from it. But it cannot take a value from a list of arguments a=
nd a type. You would need explicit emplacement construction support to do t=
hat, something like what P0032 proposes.<br><br>But if you had that, then `=
make_noncopyable_any` would be able to work with immobile types too. There&=
#39;s nothing in the wrapper that would prevent that.<br><br></div></div></=
blockquote></span><div>That's also a good idea. Note I also mentioned e=
mplacement, before I realized there is P0032.<br><br>P0135 mandates the cop=
y elision. If it is approved, then most of these problem would not exist.<b=
r>=C2=A0<br></div><span><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"><div></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"><=
div>Why bother more indirect step to do the literally correct thing (to ini=
tialize "any" object)?<br></div></div></blockquote><div><br>What =
you want is not "the literally correct thing" <i>just because you=
declare it so</i>.<br>=C2=A0</div></div></blockquote></span><div>Well, the=
type <i>`any` does not declare it is copyable literally</i> <i>by its name=
</i>, isn't it true?<br>=C2=A0<br></div><span><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div>If you think it is dangerous to allow noncopyable object=
s silently initialize the `any` object, that's fair. You want to differ=
entiate them. OK. Let's have the compromise. Why should it be out of th=
e interface of the class `any`? Can you have a constructor template with a =
special tag to indicate this use?</div></div></blockquote><div><br>That'=
;s not a "compromise"; that's <i>surrender</i>.<br><br>A &quo=
t;compromise" is where you get some of what you want, and I get some o=
f what I want. By putting the wrapper directly into the interface of `any`,=
you get <i>everything</i> you want, and I get <i>nothing</i> I want.<br><b=
r></div></div></blockquote></span><div><i>What </i>do you want to get? To n=
ot modify the working draft?<br><br>Besides the assumption in your mind, do=
you actually <i>rely on</i> that any will not throw during copying unless =
the contained object throws?<br><br>You can ignore what you does not need. =
Even if you want the type checking for copy-constructible when the feature =
I want here has changed the behavior of the constructor template `any`, jus=
t use `static_assert`. By using additional tag type, it even does not force=
you to change your code since you never use it at all. You only need one m=
ore explicit notice for your clients (and yourself): if someone dare make t=
he copy of `any` actually throwing, the behavior of the program is not guar=
anteed predictable. This<i> is </i>the status quo, <i>implicitly</i>.<br><b=
r>This <i>is </i>the compromise because it allows you to pretend the proble=
m does not exist - that <i>is</i> your gain in the case when the interface =
has changed and it does not break your code or limit you to write anything.=
It <i>is </i>a surrender to keep `any` not changed for me, because <i>whil=
e the nominal interface is disputable</i>, I actually lose something just b=
ecause someone else declared it is not cared and never used at all, and I e=
ventually have to <i>reinvent wheels</i> and pay for what I will not used a=
fter that (e.g. the binary size of dynamic library of the standard library =
implementation). Remember what the standard library is used for.<br>=C2=A0<=
br></div><span><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>Remember: by creating this wrapped `any` instance, you're introducing=
<i>fragility</i> into your codebase. It should be clear and obvious when y=
ou do this, and it should not look like normal creation of an `any` instanc=
e.</div></div></blockquote></span><div><br>This is not like normally becaus=
e of your manner of creation, which is the result. Once `any` is not `any_c=
opyable` and the implicit rules of "use copyable types" principle=
is not clarified by the standard clearly, this should be normal.<br>=C2=A0=
</div><span><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"><div>I=
t should <i>not happen by accident</i>.<br><br></div></div></blockquote></s=
pan><div>However, this is true, because any creation of `any` should not be=
the most frequent operations within such a statically typed language. So i=
s `void*`. And I don't think I should only be able to do that with an i=
ndirect layer to emphasize it in a strange, nonstandard way. <br></div><spa=
n><div>=C2=A0<br></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"><div>What I suggested is a compromise. My position is that nobody shou=
ld be able to create an `any` instance which will always throw on copy. You=
r position is that `any` should be able to accept non-copyable or immobile =
types. The compromise is that, by default you can't use non-copyable ty=
pes. But you can use a wrapper to use non-copyable types, and there's n=
othing I can do to stop you.<br>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>Even not, should the wrapper be standardized=
?<br></div></div></blockquote><div><br>Probably not. There would be some ad=
vantage to it; it would be more searchable, since everyone would not have d=
ifferent implementations.</div></div></blockquote></span><div>My main point=
is to avoid to reinvent wheels for basic need that is easily to met when n=
ot deliberately neglected. Though I agree with advantage of searching.<br>=
=C2=A0<br></div><span><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>But putting it in the standard also makes people think that using =
them is a good idea.<br><br></div></div></blockquote></span><div>No. Puttin=
g in the standard does not necessarily encourage using for anyone, it may a=
lso just because:<br><br>- Being necessary to support the language implemen=
tation.<br>- To keep compatibility with the current practice.<br>- The non =
portable replacements can not work well in near future.<br>- To avoid too m=
any wheels to be invented.<br><br>Not all of the reasons have the same effe=
ct to any interface.<br><br>People should have learned that they should use=
what they need.<br>=C2=A0<br></div><span><blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div></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"><div>However, no one was taught "any" should be=
copyable. <br></div></div></blockquote><div><br>You mean besides everyone =
who has used `boost::any` for over a decade?<br></div></div></blockquote></=
span><div><br>I don't use `boost::any` even if I would copy some reason=
able design from that (e.g. some names of member). That is trivial. I don&#=
39;t complain about `boost::any` here, because it is prefixed with `boost::=
`, which indicates it has no power to define <i>what </i>is C++, which is n=
ot I cared here. I can ignore that design if I do not think it is good enou=
gh.<br><br>But all C++ users should face the standard, directly or indirect=
ly, or they were not learning C++, but a flavored dialect. Once an interfac=
e fixed in the standard, the future change would cost probably much, not on=
ly in the language, but also for implementations and mind of users.<br><br>=
</div><span><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"><div>=
=C2=A0</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"><div> =
That's also why someone will be surprised.<br></div></div></blockquote>=
<div><br>I don't care.<br><br></div></div></blockquote></span><div>And =
you still cannot persuade me that the current design <i>has done the right =
thing</i> undoubtfully, that means you can't assert a change will not b=
e considerable. Before you have proven anyone should not care it, it deserv=
es.<br>=C2=A0<br></div><span><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></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>Also, do you really want to argue "possible misconception to new use=
rs"? Don't you think users will find it far more surprising that a=
type that is supposedly copyable will emit an exception on copy for seemin=
gly no reason? Not to mention that such surprises will be <i>runtime errors=
</i>, rather than compile-time failures...<br><br></div></div></blockquote>=
<div>They should not be so surprised if they know what type erasure stands =
for.<br></div></div></blockquote><div><br>... what? The concept of type era=
sure has nothing at all to do with the behavior of a value type or referenc=
e type. You can make a type-erased copyable value type (aka: `any`). You ca=
n make a type-erased moveable value type (`unique_any`). You can make a typ=
e-erased non-owning reference type. You can make a type-erased owning refer=
ence type (`shared_any`). And so forth.<br><br>The concept of type erasure =
does not in any way conflict with the concept of copying. So knowing about =
type erasure does not in any way require you to believe that a type-erased =
type would not be copyable. Again, see `std::function`.</div></div></blockq=
uote></span><div>It should not depend on copying, either. It should be the =
representative of type-erased because of its naming, but why with unrelated=
limitations?<br>Function does not matter much because it is "function=
", not "any". Though `std::function` is still not enough in =
practice, but it is another topic.<br>=C2=A0<br></div></div><span>
<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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
21hSTDlzBAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"21hSTDlzBAAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'=
;javascript:';return true;">std-pr...@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/be43d58f-39c5-4315-bba2-de9ec9e6aa96%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D'https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/be43d58f-39c5-4315-bba2-de9ec9e6aa96%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter';return true;" on=
click=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/be43d58f-39c5-4315-bba2-de9ec9e6aa96%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter';return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/be43d58f-39c5-4315-<wbr>bba2-=
de9ec9e6aa96%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></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/92c6463b-dc6d-4b4d-84c2-b421be98d3a4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/92c6463b-dc6d-4b4d-84c2-b421be98d3a4=
%40isocpp.org</a>.<br />
------=_Part_6656_1898852002.1461912939854--
------=_Part_6655_276136394.1461912939853--
.