Topic: Deep copying smart pointer
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Thu, 7 Jan 2016 07:51:31 +0000
Raw View
A deep copying smart pointer that uses type erasure to call the copy constr=
uctor of derived types would allow the compiler-generated copy constructor =
to copy an object composed of polymorphic components correctly.
When component objects are owned by deep-copying pointers, they will be cop=
ied correctly without any extra code being required.
I'm currently working with pre c++11 code with lots of composite objects wi=
th user-defined destructors and copy constructors. Using unique pointers wi=
ll get rid of the need for user-defined destructors. Using deep copying poi=
nters will get rid of the need for user-defined copy constructors too.
Would this be of interest to others?
Regards?
Jonathan
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 7 Jan 2016 16:06:23 +0200
Raw View
On 7 January 2016 at 09:51, Jonathan Coe <jonathanbcoe@gmail.com> wrote:
> A deep copying smart pointer that uses type erasure to call the copy cons=
tructor of derived types would allow the compiler-generated copy constructo=
r to copy an object composed of polymorphic components correctly.
>
> When component objects are owned by deep-copying pointers, they will be c=
opied correctly without any extra code being required.
>
> I'm currently working with pre c++11 code with lots of composite objects =
with user-defined destructors and copy constructors. Using unique pointers =
will get rid of the need for user-defined destructors. Using deep copying p=
ointers will get rid of the need for user-defined copy constructors too.
>
> Would this be of interest to others?
Yes, it would. There's an existing proposal at
http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3339.pdf
but that one doesn't do type erasure. I have done some implementation work
on a type-erasing approach, but I didn't polish it far enough to make
it a proposal.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Thu, 7 Jan 2016 16:34:48 +0000
Raw View
> On 7 Jan 2016, at 14:06, Ville Voutilainen <ville.voutilainen@gmail.com> =
wrote:
>=20
>> On 7 January 2016 at 09:51, Jonathan Coe <jonathanbcoe@gmail.com> wrote:
>> A deep copying smart pointer that uses type erasure to call the copy con=
structor of derived types would allow the compiler-generated copy construct=
or to copy an object composed of polymorphic components correctly.
>>=20
>> When component objects are owned by deep-copying pointers, they will be =
copied correctly without any extra code being required.
>>=20
>> I'm currently working with pre c++11 code with lots of composite objects=
with user-defined destructors and copy constructors. Using unique pointers=
will get rid of the need for user-defined destructors. Using deep copying =
pointers will get rid of the need for user-defined copy constructors too.
>>=20
>> Would this be of interest to others?
>=20
>=20
> Yes, it would. There's an existing proposal at
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3339.pdf
> but that one doesn't do type erasure. I have done some implementation wor=
k
> on a type-erasing approach, but I didn't polish it far enough to make
> it a proposal.
>=20
> --=20
>=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=
email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-prop=
osals/.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Thu, 7 Jan 2016 14:35:23 -0800 (PST)
Raw View
------=_Part_2_1436900396.1452206123720
Content-Type: text/plain; charset=UTF-8
How can this be implemented? Can you explain this briefly? What would the limitations be?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2_1436900396.1452206123720--
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Thu, 7 Jan 2016 22:49:17 +0000
Raw View
--001a1143ebecdc20c10528c64781
Content-Type: text/plain; charset=UTF-8
I have a preliminary implementation. I use a buffer to store a type-erased
implementation object templated on the derived type. Raw pointers can be
passed in to the constructor and stored without the need for copying of the
pointee.
Limits I can think of are inability to define functions as constexpr (due
to the use of a buffer) and the need for derived types to be copy
constructible themselves.
The first limit may be a QoI issue. The second seems pretty fundamental.
Regards,
Jonathan
On 7 January 2016 at 22:35, Bengt Gustafsson <bengt.gustafsson@beamways.com>
wrote:
> How can this be implemented? Can you explain this briefly? What would the
> limitations be?
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a1143ebecdc20c10528c64781
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I have a preliminary implementation. I use a buffer to sto=
re a type-erased implementation object templated on the derived type. Raw p=
ointers can be passed in to the constructor and stored without the need for=
copying of the pointee.<div><br></div><div>Limits I can think of are inabi=
lity to define functions as constexpr (due to the use of a buffer) and the =
need for derived types to be copy constructible themselves.</div><div><br><=
/div><div>The first limit may be a QoI issue. The second seems pretty funda=
mental.</div><div><br></div><div>Regards,</div><div><br></div><div>Jonathan=
</div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On 7 =
January 2016 at 22:35, Bengt Gustafsson <span dir=3D"ltr"><<a href=3D"ma=
ilto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustafsson@beam=
ways.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">How can =
this be implemented? Can you explain this briefly? What would the limitatio=
ns be?<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a1143ebecdc20c10528c64781--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 7 Jan 2016 16:59:28 -0600
Raw View
--001a113ecd9a9eb1d90528c66ec4
Content-Type: text/plain; charset=UTF-8
On 7 January 2016 at 16:49, Jonathan Coe <jbcoe@me.com> wrote:
> I have a preliminary implementation. I use a buffer to store a type-erased
> implementation object templated on the derived type.
>
Do you fall back on the heap if the object is too large for the buffer? Of
course, that would imply allocator support in a proposal. Given that
derived types may be arbitrarily large, I don't see any way around that.
> Raw pointers can be passed in to the constructor and stored without the
> need for copying of the pointee.
>
Does that transfer ownership, and if so, how does the clone_ptr know how to
"clean up" what is pointed to?
And if it doesn't transfer ownership, this sounds like a very complicated
ownership model.
I'm not a fan of "sometimes owned" semantics, as I've had to fix far too
many bugs based on it in other people's code.
--
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113ecd9a9eb1d90528c66ec4
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 7 January 2016 at 16:49, Jonathan Coe <span dir=3D"ltr"=
><<a href=3D"mailto:jbcoe@me.com" target=3D"_blank">jbcoe@me.com</a>>=
</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr">I have a preliminary implement=
ation. I use a buffer to store a type-erased implementation object template=
d on the derived type. </div></blockquote><div><br></div><div>Do you fall b=
ack on the heap if the object is too large for the buffer?=C2=A0 Of course,=
that would imply allocator support in a proposal.=C2=A0 Given that derived=
types may be arbitrarily large, I don't see any way around that.</div>=
<div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Raw pointe=
rs can be passed in to the constructor and stored without the need for copy=
ing of the pointee.</div></blockquote><div><br></div><div>Does that transfe=
r ownership, and if so, how does the clone_ptr know how to "clean up&q=
uot; what is pointed to?</div><div><br></div><div>And if it doesn't tra=
nsfer ownership, this sounds like a very complicated ownership model.</div>=
<div><br></div><div>I'm not a fan of "sometimes owned" semant=
ics, as I've had to fix far too many bugs based on it in other people&#=
39;s code.</div></div>-- <br><div class=3D"gmail_signature"><div dir=3D"ltr=
"><div><div dir=3D"ltr"><div>=C2=A0Nevin ":-)" Liber=C2=A0 <ma=
ilto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@evil=
overlord.com</a>> =C2=A0+1-847-691-1404</div></div></div></div></div>
</div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a113ecd9a9eb1d90528c66ec4--
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Thu, 7 Jan 2016 23:12:01 +0000
Raw View
--047d7b86eaac2b54b80528c6999e
Content-Type: text/plain; charset=UTF-8
On 7 January 2016 at 22:59, Nevin Liber <nevin@eviloverlord.com> wrote:
> On 7 January 2016 at 16:49, Jonathan Coe <jbcoe@me.com> wrote:
>
>> I have a preliminary implementation. I use a buffer to store a
>> type-erased implementation object templated on the derived type.
>>
>
> Do you fall back on the heap if the object is too large for the buffer?
> Of course, that would imply allocator support in a proposal. Given that
> derived types may be arbitrarily large, I don't see any way around that.
>
The buffer stores a type-erasure implementation object that contains the
pointer passed into the constructor (not the pointee) so the size is known
for any derived type (pointer + vtable pointer).
>
>> Raw pointers can be passed in to the constructor and stored without the
>> need for copying of the pointee.
>>
>
> Does that transfer ownership, and if so, how does the clone_ptr know how
> to "clean up" what is pointed to?
>
>
The pointer passed in is owned (like shared_ptr and unique_ptr).
The deep_ptr unambiguously owns the pointer it is passed so will clean it
up (like unique_ptr or boost::scoped_ptr).
Type erasure is used to call the derived class destructor (like shared_ptr).
Jon
> And if it doesn't transfer ownership, this sounds like a very complicated
> ownership model.
>
> I'm not a fan of "sometimes owned" semantics, as I've had to fix far too
> many bugs based on it in other people's code.
> --
> 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.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b86eaac2b54b80528c6999e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 7 January 2016 at 22:59, Nevin Liber <span dir=3D"ltr">=
<<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@evilo=
verlord.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><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"><div dir=3D"ltr"><span class=3D"">On 7 Ja=
nuary 2016 at 16:49, Jonathan Coe <span dir=3D"ltr"><<a href=3D"mailto:j=
bcoe@me.com" target=3D"_blank">jbcoe@me.com</a>></span> wrote:<br></span=
><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D""><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-lef=
t-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padd=
ing-left:1ex"><div dir=3D"ltr">I have a preliminary implementation. I use a=
buffer to store a type-erased implementation object templated on the deriv=
ed type. </div></blockquote><div><br></div></span><div>Do you fall back on =
the heap if the object is too large for the buffer?=C2=A0 Of course, that w=
ould imply allocator support in a proposal.=C2=A0 Given that derived types =
may be arbitrarily large, I don't see any way around that.</div></div><=
/div></div></blockquote><div class=3D"gmail_quote"><br></div><div>The buffe=
r stores a type-erasure implementation object that contains the pointer pas=
sed into the constructor (not the pointee) so the size is known for any der=
ived type (pointer + vtable pointer).</div><div><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">=
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><spa=
n class=3D""><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,=
204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">Raw pointer=
s can be passed in to the constructor and stored without the need for copyi=
ng of the pointee.</div></blockquote><div><br></div></span><div>Does that t=
ransfer ownership, and if so, how does the clone_ptr know how to "clea=
n up" what is pointed to?</div><div><br></div></div></div></div></bloc=
kquote><div>=C2=A0</div><div>The pointer passed in is owned (like shared_pt=
r and unique_ptr).</div><div>The deep_ptr unambiguously owns the pointer it=
is passed so will clean it up (like unique_ptr or boost::scoped_ptr).<br><=
/div><div>Type erasure is used to call the derived class destructor (like s=
hared_ptr).</div><div><br></div><div>Jon=C2=A0</div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-w=
idth:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding=
-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_=
quote"><div></div><div>And if it doesn't transfer ownership, this sound=
s like a very complicated ownership model.</div><div><br></div><div>I'm=
not a fan of "sometimes owned" semantics, as I've had to fix=
far too many bugs based on it in other people's code.</div></div><span=
class=3D""><font color=3D"#888888">-- <br><div><div dir=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" value=3D"+18476911404" tar=
get=3D"_blank">+1-847-691-1404</a></div></div></div></div></div>
</font></span></div></div><div class=3D""><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7b86eaac2b54b80528c6999e--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 7 Jan 2016 17:39:03 -0600
Raw View
--089e013a1f1629d2710528c6fc91
Content-Type: text/plain; charset=UTF-8
On 7 January 2016 at 17:12, Jonathan Coe <jbcoe@me.com> wrote:
> On 7 January 2016 at 22:59, Nevin Liber <nevin@eviloverlord.com> wrote:
>
>> On 7 January 2016 at 16:49, Jonathan Coe <jbcoe@me.com> wrote:
>>
>>> I have a preliminary implementation. I use a buffer to store a
>>> type-erased implementation object templated on the derived type.
>>>
>>
>> Do you fall back on the heap if the object is too large for the buffer?
>> Of course, that would imply allocator support in a proposal. Given that
>> derived types may be arbitrarily large, I don't see any way around that.
>>
>
> The buffer stores a type-erasure implementation object that contains the
> pointer passed into the constructor (not the pointee) so the size is known
> for any derived type (pointer + vtable pointer).
>
Ah, I see.
>
>
>>
>>> Raw pointers can be passed in to the constructor and stored without the
>>> need for copying of the pointee.
>>>
>>
>> Does that transfer ownership, and if so, how does the clone_ptr know how
>> to "clean up" what is pointed to?
>>
>>
> The pointer passed in is owned (like shared_ptr and unique_ptr).
> The deep_ptr unambiguously owns the pointer it is passed so will clean it
> up (like unique_ptr or boost::scoped_ptr).
> Type erasure is used to call the derived class destructor (like
> shared_ptr).
>
That isn't the problem.
Both unique_ptr and shared_ptr also have a deleter that knows how to clean
up. However, neither has to do allocation, while clone_ptr does. Would
you be proposing that the allocator be part of the type, require
polymorphic allocators (from Lib Fundamentals 2) or do you have some other
scheme in mind?
--
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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e013a1f1629d2710528c6fc91
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 7 January 2016 at 17:12, Jonathan Coe <span dir=3D"ltr"=
><<a href=3D"mailto:jbcoe@me.com" target=3D"_blank">jbcoe@me.com</a>>=
</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><span>On 7 January 2016 at 22:=
59, Nevin Liber <span dir=3D"ltr"><<a href=3D"mailto:nevin@eviloverlord.=
com" target=3D"_blank">nevin@eviloverlord.com</a>></span> wrote:<br></sp=
an><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:=
1ex"><div dir=3D"ltr"><span>On 7 January 2016 at 16:49, Jonathan Coe <span =
dir=3D"ltr"><<a href=3D"mailto:jbcoe@me.com" target=3D"_blank">jbcoe@me.=
com</a>></span> wrote:<br></span><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><span><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bo=
rder-left-style:solid;padding-left:1ex"><div dir=3D"ltr">I have a prelimina=
ry implementation. I use a buffer to store a type-erased implementation obj=
ect templated on the derived type. </div></blockquote><div><br></div></span=
><div>Do you fall back on the heap if the object is too large for the buffe=
r?=C2=A0 Of course, that would imply allocator support in a proposal.=C2=A0=
Given that derived types may be arbitrarily large, I don't see any way=
around that.</div></div></div></div></blockquote><div class=3D"gmail_quote=
"><br></div></span><div>The buffer stores a type-erasure implementation obj=
ect that contains the pointer passed into the constructor (not the pointee)=
so the size is known for any derived type (pointer + vtable pointer).</div=
></div></div></div></blockquote><div><br></div><div>Ah, I see.=C2=A0</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"><div class=3D"gmail_extra"><=
div class=3D"gmail_quote"><span><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-c=
olor:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D=
"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex"><div dir=3D"ltr">Raw pointers can be passed in to=
the constructor and stored without the need for copying of the pointee.</d=
iv></blockquote><div><br></div></span><div>Does that transfer ownership, an=
d if so, how does the clone_ptr know how to "clean up" what is po=
inted to?</div><div><br></div></div></div></div></blockquote><div>=C2=A0</d=
iv></span><div>The pointer passed in is owned (like shared_ptr and unique_p=
tr).</div><div>The deep_ptr unambiguously owns the pointer it is passed so =
will clean it up (like unique_ptr or boost::scoped_ptr).<br></div><div>Type=
erasure is used to call the derived class destructor (like shared_ptr).</d=
iv></div></div></div></blockquote><div><br></div><div>That isn't the pr=
oblem.</div><div><br></div><div>Both unique_ptr and shared_ptr also have a =
deleter that knows how to clean up.=C2=A0 However, neither has to do alloca=
tion, while clone_ptr does.=C2=A0 Would you be proposing that the allocator=
be part of the type, require polymorphic allocators (from Lib Fundamentals=
2) or do you have some other scheme in mind?</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 />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--089e013a1f1629d2710528c6fc91--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 8 Jan 2016 01:43:44 +0200
Raw View
On 8 January 2016 at 01:39, Nevin Liber <nevin@eviloverlord.com> wrote:
>> The pointer passed in is owned (like shared_ptr and unique_ptr).
>> The deep_ptr unambiguously owns the pointer it is passed so will clean it
>> up (like unique_ptr or boost::scoped_ptr).
>> Type erasure is used to call the derived class destructor (like
>> shared_ptr).
> That isn't the problem.
> Both unique_ptr and shared_ptr also have a deleter that knows how to clean
> up. However, neither has to do allocation, while clone_ptr does. Would you
> be proposing that the allocator be part of the type, require polymorphic
> allocators (from Lib Fundamentals 2) or do you have some other scheme in
> mind?
I have outlined a scheme where the allocation happens in a cloner, which is
also a deleter. That way people who want allocator support can do it in a custom
cloner. I have a default cloner that just allocates on free store, but
the implementation
allows bypassing that functionality. The implementation is very much
incomplete, but
it has some bits that Jonathan's implementation doesn't have and vice versa.
The current implementation I have actually tries to support
allocators. I want to drop
that, because propagation traits don't mix with type erasure, so I
plan to remove specific
allocator support and provide the most minimal of allocator support,
which is just supporting
custom cloners.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 8 Jan 2016 01:45:01 +0200
Raw View
On 8 January 2016 at 01:43, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
>> Both unique_ptr and shared_ptr also have a deleter that knows how to clean
>> up. However, neither has to do allocation, while clone_ptr does. Would you
>> be proposing that the allocator be part of the type, require polymorphic
>> allocators (from Lib Fundamentals 2) or do you have some other scheme in
>> mind?
>
> I have outlined a scheme where the allocation happens in a cloner, which is
> also a deleter. That way people who want allocator support can do it in a custom
> cloner. I have a default cloner that just allocates on free store, but
> the implementation
> allows bypassing that functionality. The implementation is very much
> incomplete, but
> it has some bits that Jonathan's implementation doesn't have and vice versa.
>
> The current implementation I have actually tries to support
> allocators. I want to drop
> that, because propagation traits don't mix with type erasure, so I
> plan to remove specific
> allocator support and provide the most minimal of allocator support,
> which is just supporting
> custom cloners.
I should probably add that the cloner is also type-erased, quite like
the deleter
of a shared_ptr is.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Fri, 8 Jan 2016 01:38:31 +0100
Raw View
--089e0160a9367e5c4c0528c7ce2f
Content-Type: text/plain; charset=UTF-8
On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <jonathanbcoe@gmail.com> wrote:
> A deep copying smart pointer that uses type erasure to call the copy
> constructor of derived types would allow the compiler-generated copy
> constructor to copy an object composed of polymorphic components correctly.
>
Do you mean something like:
std::derived<Animal> animal1 = std::make_derived<Animal>(dog); // Dog
deduced from dog
std::derived<Animal> animal2 = animal1; // calls Dog::Dog(const Dog&)
If so, couldn't std::derived<B> be a simple adapter around std::any, with
the added invariant that the contained object be derived from B.
Or do I miss something?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0160a9367e5c4c0528c7ce2f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <span dir=3D"ltr"><<a h=
ref=3D"mailto:jonathanbcoe@gmail.com" target=3D"_blank">jonathanbcoe@gmail.=
com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,2=
04);border-left-style:solid;padding-left:1ex">A deep copying smart pointer =
that uses type erasure to call the copy constructor of derived types would =
allow the compiler-generated copy constructor to copy an object composed of=
polymorphic components correctly.<br></blockquote><div><br></div><div>Do y=
ou mean something like:</div><div><br></div><div><div>std::derived<Anima=
l> animal1 =3D std::make_derived<Animal>(dog); // Dog deduced from=
dog</div><div>std::derived<Animal> animal2 =3D animal1; =C2=A0// cal=
ls Dog::Dog(const Dog&)</div></div><div><br></div><div>If so, couldn=
9;t std::derived<B> be a simple adapter around std::any, with the add=
ed invariant that the contained object be derived from B.</div><div><br></d=
iv><div>Or do I miss something?</div><div><br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--089e0160a9367e5c4c0528c7ce2f--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 8 Jan 2016 03:14:10 +0200
Raw View
On 8 January 2016 at 02:38, Andrew Tomazos <andrewtomazos@gmail.com> wrote:
>
>
> On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <jonathanbcoe@gmail.com> wrote:
>>
>> A deep copying smart pointer that uses type erasure to call the copy
>> constructor of derived types would allow the compiler-generated copy
>> constructor to copy an object composed of polymorphic components correctly.
>
>
> Do you mean something like:
>
> std::derived<Animal> animal1 = std::make_derived<Animal>(dog); // Dog
> deduced from dog
> std::derived<Animal> animal2 = animal1; // calls Dog::Dog(const Dog&)
>
> If so, couldn't std::derived<B> be a simple adapter around std::any, with
> the added invariant that the contained object be derived from B.
>
> Or do I miss something?
That would be a different thing. Sean Parent has envisioned an Any<T>
almost like that,
but having this thing be a smart pointer allows for certain benefits,
if we so choose:
- it can always do a noexcept move, even for types that are not movable
- it doesn't need to clone the incoming value on
construction/assignment, it can just adopt
the pointer
- Any<T> could do it as well, but as opposed to a an actual wrapper on any,
it doesn't necessarily need to require CopyConstructible for T.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 8 Jan 2016 02:26:50 -0800 (PST)
Raw View
------=_Part_452_310793092.1452248810962
Content-Type: multipart/alternative;
boundary="----=_Part_453_1547946153.1452248810963"
------=_Part_453_1547946153.1452248810963
Content-Type: text/plain; charset=UTF-8
I still don't see a solution to the main cloning problem. I read n3339 but
the "strawman" code was too much to take in, it would be better with a very
slimmed down version which shows what it can accomplish. I assume that we
can never get this to work:
class Base {
};
class Sub : public Base {
};
Base* b = new Sub;
clone_ptr<Base> p = b;
clone_ptr<Base> p2 = p; // No knowledge of the existence of class Sub
exists here...
So I assume that you shoot for a lesser target, but exactly what is that
target and how do you prevent people from trying to use it as in my
example? How many of the interesting use cases remain if my example doesn't
work?
My take on this would be to introduce a trait on Base which indicates the
name of a virtual method in Base that can be used for cloning. Maybe this
is what you indend, but I haven't seen a comprehensible description.
While small object optimization can be interesting in this scenario I think
that is a separate discussion. (it would require a CloneAt(void*, Base*)
method as well as a ByteCount() method in Base.
The problem with the virtual clone method is that it is so easy to forget
to reimplement it in each subclass. Can anyone come up with a language
feature which automates this?
Den fredag 8 januari 2016 kl. 02:14:12 UTC+1 skrev Ville Voutilainen:
>
> On 8 January 2016 at 02:38, Andrew Tomazos <andrew...@gmail.com
> <javascript:>> wrote:
> >
> >
> > On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <jonath...@gmail.com
> <javascript:>> wrote:
> >>
> >> A deep copying smart pointer that uses type erasure to call the copy
> >> constructor of derived types would allow the compiler-generated copy
> >> constructor to copy an object composed of polymorphic components
> correctly.
> >
> >
> > Do you mean something like:
> >
> > std::derived<Animal> animal1 = std::make_derived<Animal>(dog); // Dog
> > deduced from dog
> > std::derived<Animal> animal2 = animal1; // calls Dog::Dog(const Dog&)
> >
> > If so, couldn't std::derived<B> be a simple adapter around std::any,
> with
> > the added invariant that the contained object be derived from B.
> >
> > Or do I miss something?
>
>
> That would be a different thing. Sean Parent has envisioned an Any<T>
> almost like that,
> but having this thing be a smart pointer allows for certain benefits,
> if we so choose:
> - it can always do a noexcept move, even for types that are not movable
> - it doesn't need to clone the incoming value on
> construction/assignment, it can just adopt
> the pointer
> - Any<T> could do it as well, but as opposed to a an actual wrapper on
> any,
> it doesn't necessarily need to require CopyConstructible for T.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_453_1547946153.1452248810963
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>I still don't see a solution to the main cloning =
problem. I read n3339 but the "strawman" code was too much to tak=
e in, it would be better with a very slimmed down version which shows what =
it can accomplish. I assume that we can never get this to work:</div><div><=
br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187=
, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code=
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: =
#008;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Base</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Sub</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">public</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify=
">Base</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
#606;" class=3D"styled-by-prettify">Base</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> b </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>new</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Sub</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>clone_ptr</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Base</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> p </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>clone_ptr</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y"><</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Bas=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> p2 </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> p</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0</span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// No knowledge of the existence o=
f class Sub exists here...</span></div></code></div><div><br></div><div><br=
></div><div>So I assume that you shoot for a lesser target, but exactly wha=
t is that target and how do you prevent people from trying to use it as in =
my example? How many of the interesting use cases remain if my example does=
n't work?</div><div><br></div><div>My take on this would be to introduc=
e a trait on Base which indicates the name of a virtual method in Base that=
can be used for cloning. Maybe this is what you indend, but I haven't =
seen a comprehensible description.</div><div><br></div><div>While small obj=
ect optimization can be interesting in this scenario I think that is a sepa=
rate discussion. (it would require a CloneAt(void*, Base*) method as well a=
s a ByteCount() method in Base.</div><div><br></div><div>The problem with t=
he virtual clone method is that it is so easy to forget to reimplement it i=
n each subclass. Can anyone come up with a language feature which automates=
this?<br><br>Den fredag 8 januari 2016 kl. 02:14:12 UTC+1 skrev Ville Vout=
ilainen:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 8 January 2016 at 0=
2:38, Andrew Tomazos <<a href=3D"javascript:" target=3D"_blank" gdf-obfu=
scated-mailto=3D"_nsWO3ggFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D=
'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">andrew...@gmail.com</a>> wrote:
<br>>
<br>>
<br>> On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <<a href=3D"javasc=
ript:" target=3D"_blank" gdf-obfuscated-mailto=3D"_nsWO3ggFAAJ" rel=3D"nofo=
llow" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">jonath...@gmail.com</a=
>> wrote:
<br>>>
<br>>> A deep copying smart pointer that uses type erasure to call th=
e copy
<br>>> constructor of derived types would allow the compiler-generate=
d copy
<br>>> constructor to copy an object composed of polymorphic componen=
ts correctly.
<br>>
<br>>
<br>> Do you mean something like:
<br>>
<br>> std::derived<Animal> animal1 =3D std::make_derived<Animal=
>(dog)<wbr>; // Dog
<br>> deduced from dog
<br>> std::derived<Animal> animal2 =3D animal1; =C2=A0// calls Dog=
::Dog(const Dog&)
<br>>
<br>> If so, couldn't std::derived<B> be a simple adapter arou=
nd std::any, with
<br>> the added invariant that the contained object be derived from B.
<br>>
<br>> Or do I miss something?
<br>
<br>
<br>That would be a different thing. Sean Parent has envisioned an Any<T=
>
<br>almost like that,
<br>but having this thing be a smart pointer allows for certain benefits,
<br>if we so choose:
<br>- it can always do a noexcept move, even for types that are not movable
<br>- it doesn't need to clone the incoming value on
<br>construction/assignment, it can just adopt
<br>the pointer
<br>- Any<T> could do it as well, but as opposed to a an actual wrapp=
er on any,
<br>it doesn't necessarily need to require CopyConstructible for T.
<br></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_453_1547946153.1452248810963--
------=_Part_452_310793092.1452248810962--
.
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Fri, 8 Jan 2016 11:22:01 +0000
Raw View
> On 8 Jan 2016, at 10:26, Bengt Gustafsson <bengt.gustafsson@beamways.com> wrote:
>
> I still don't see a solution to the main cloning problem. I read n3339 but the "strawman" code was too much to take in, it would be better with a very slimmed down version which shows what it can accomplish. I assume that we can never get this to work:
>
> class Base {
> };
>
> class Sub : public Base {
> };
>
> Base* b = new Sub;
> clone_ptr<Base> p = b;
> clone_ptr<Base> p2 = p; // No knowledge of the existence of class Sub exists here...
>
That's an important point. My (updated) design only allows construction of deep_ptr from another deep_ptr or using a make_deep_ptr function template that (like make_unique) takes constructor arguments. This 'lesser target' will meet my requirements.
>
> So I assume that you shoot for a lesser target, but exactly what is that target and how do you prevent people from trying to use it as in my example? How many of the interesting use cases remain if my example doesn't work?
>
> My take on this would be to introduce a trait on Base which indicates the name of a virtual method in Base that can be used for cloning. Maybe this is what you indend, but I haven't seen a comprehensible description.
>
> While small object optimization can be interesting in this scenario I think that is a separate discussion. (it would require a CloneAt(void*, Base*) method as well as a ByteCount() method in Base.
>
> The problem with the virtual clone method is that it is so easy to forget to reimplement it in each subclass. Can anyone come up with a language feature which automates this?
>
> Den fredag 8 januari 2016 kl. 02:14:12 UTC+1 skrev Ville Voutilainen:
> On 8 January 2016 at 02:38, Andrew Tomazos <andrew...@gmail.com> wrote:
> >
> >
> > On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <jonath...@gmail.com> wrote:
> >>
> >> A deep copying smart pointer that uses type erasure to call the copy
> >> constructor of derived types would allow the compiler-generated copy
> >> constructor to copy an object composed of polymorphic components correctly.
> >
> >
> > Do you mean something like:
> >
> > std::derived<Animal> animal1 = std::make_derived<Animal>(dog); // Dog
> > deduced from dog
> > std::derived<Animal> animal2 = animal1; // calls Dog::Dog(const Dog&)
> >
> > If so, couldn't std::derived<B> be a simple adapter around std::any, with
> > the added invariant that the contained object be derived from B.
> >
> > Or do I miss something?
>
>
> That would be a different thing. Sean Parent has envisioned an Any<T>
> almost like that,
> but having this thing be a smart pointer allows for certain benefits,
> if we so choose:
> - it can always do a noexcept move, even for types that are not movable
> - it doesn't need to clone the incoming value on
> construction/assignment, it can just adopt
> the pointer
> - Any<T> could do it as well, but as opposed to a an actual wrapper on any,
> it doesn't necessarily need to require CopyConstructible for T.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 8 Jan 2016 03:40:45 -0800 (PST)
Raw View
------=_Part_482_1886001312.1452253245837
Content-Type: multipart/alternative;
boundary="----=_Part_483_1608580616.1452253245843"
------=_Part_483_1608580616.1452253245843
Content-Type: text/plain; charset=UTF-8
That's what I suspected. Only allowing construction with a make_ function
seems rather restrictive though. The N3339 seems to require an explicit
Cloner template parameter to indicate how to clone the pointees. The trait
idea could be combined with your make_ function (which we do want anyway
for consistency) so that IF the trait is defined for a base class of the T
class of the pointer then a reset() function taking a T* is available on
the pointer. The trait is not to have a default implementation:
template<typename T> struct clone_trait;
// Application code to make Base clonable:
template<> struct clone_trait<Base> {
static Base* clone(const Base* src) { return src->Clone(); } //
Assuming Base has a Clone method.
};
Or maybe, to avoid the namespace issues better, an overloadable function
with a fixed name. I assume your make_ function stores a function pointer
to the copy constructor. It should be possible to wrap either this or the
trait method into an object that can be stored in the clone_ptr for future
use.
Den fredag 8 januari 2016 kl. 12:22:06 UTC+1 skrev Jonathan Coe:
>
>
> > On 8 Jan 2016, at 10:26, Bengt Gustafsson <bengt.gu...@beamways.com
> <javascript:>> wrote:
> >
> > I still don't see a solution to the main cloning problem. I read n3339
> but the "strawman" code was too much to take in, it would be better with a
> very slimmed down version which shows what it can accomplish. I assume that
> we can never get this to work:
> >
> > class Base {
> > };
> >
> > class Sub : public Base {
> > };
> >
> > Base* b = new Sub;
> > clone_ptr<Base> p = b;
> > clone_ptr<Base> p2 = p; // No knowledge of the existence of class
> Sub exists here...
> >
>
> That's an important point. My (updated) design only allows construction of
> deep_ptr from another deep_ptr or using a make_deep_ptr function template
> that (like make_unique) takes constructor arguments. This 'lesser target'
> will meet my requirements.
>
> >
> > So I assume that you shoot for a lesser target, but exactly what is that
> target and how do you prevent people from trying to use it as in my
> example? How many of the interesting use cases remain if my example doesn't
> work?
> >
> > My take on this would be to introduce a trait on Base which indicates
> the name of a virtual method in Base that can be used for cloning. Maybe
> this is what you indend, but I haven't seen a comprehensible description.
> >
> > While small object optimization can be interesting in this scenario I
> think that is a separate discussion. (it would require a CloneAt(void*,
> Base*) method as well as a ByteCount() method in Base.
> >
> > The problem with the virtual clone method is that it is so easy to
> forget to reimplement it in each subclass. Can anyone come up with a
> language feature which automates this?
> >
> > Den fredag 8 januari 2016 kl. 02:14:12 UTC+1 skrev Ville Voutilainen:
> > On 8 January 2016 at 02:38, Andrew Tomazos <andrew...@gmail.com> wrote:
> > >
> > >
> > > On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <jonath...@gmail.com>
> wrote:
> > >>
> > >> A deep copying smart pointer that uses type erasure to call the copy
> > >> constructor of derived types would allow the compiler-generated copy
> > >> constructor to copy an object composed of polymorphic components
> correctly.
> > >
> > >
> > > Do you mean something like:
> > >
> > > std::derived<Animal> animal1 = std::make_derived<Animal>(dog); // Dog
> > > deduced from dog
> > > std::derived<Animal> animal2 = animal1; // calls Dog::Dog(const Dog&)
> > >
> > > If so, couldn't std::derived<B> be a simple adapter around std::any,
> with
> > > the added invariant that the contained object be derived from B.
> > >
> > > Or do I miss something?
> >
> >
> > That would be a different thing. Sean Parent has envisioned an Any<T>
> > almost like that,
> > but having this thing be a smart pointer allows for certain benefits,
> > if we so choose:
> > - it can always do a noexcept move, even for types that are not movable
> > - it doesn't need to clone the incoming value on
> > construction/assignment, it can just adopt
> > the pointer
> > - Any<T> could do it as well, but as opposed to a an actual wrapper on
> any,
> > it doesn't necessarily need to require CopyConstructible for T.
> >
> > --
> >
> > ---
> > 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-proposal...@isocpp.org <javascript:>.
> > To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>
> > Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_483_1608580616.1452253245843
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">That's what I suspected. Only allowing construction wi=
th a make_ function seems rather restrictive though. The N3339 seems to req=
uire an explicit Cloner template parameter to indicate how to clone the poi=
ntees. The trait idea could be combined with your make_ function (which we =
do want anyway for consistency) so that IF the trait is defined for a base =
class of the T class of the pointer then a reset() function taking a T* is =
available on the pointer. The trait is not to have a default implementation=
:<div><br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(1=
87, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">template</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> clone_trait</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br><br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// Application code to make Base clonable:</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify"><></span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> clone_trait</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Base</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">sta=
tic</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Base</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> clone</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Base</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> src</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> src</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">-></span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">Clone</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 </=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Assuming =
Base has a Clone method.</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br><br><br></span></div></code></div><div><div><div><br><br></div><div>Or =
maybe, to avoid the namespace issues better, an overloadable function with =
a fixed name. I assume your make_ function stores a function pointer to the=
copy constructor. It should be possible to wrap either this or the trait m=
ethod into an object that can be stored in the clone_ptr for future use.<br=
><br>Den fredag 8 januari 2016 kl. 12:22:06 UTC+1 skrev Jonathan Coe:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;">
<br>> On 8 Jan 2016, at 10:26, Bengt Gustafsson <<a href=3D"javascrip=
t:" target=3D"_blank" gdf-obfuscated-mailto=3D"C5l7YaRBFAAJ" rel=3D"nofollo=
w" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;">bengt.gu...@beamways.co=
m</a><wbr>> wrote:
<br>>=20
<br>> I still don't see a solution to the main cloning problem. I re=
ad n3339 but the "strawman" code was too much to take in, it woul=
d be better with a very slimmed down version which shows what it can accomp=
lish. I assume that we can never get this to work:
<br>>=20
<br>> class Base {
<br>> };
<br>>=20
<br>> class Sub : public Base {
<br>> };
<br>>=20
<br>> Base* b =3D new Sub;
<br>> clone_ptr<Base> p =3D b;
<br>> clone_ptr<Base> p2 =3D p; =C2=A0 =C2=A0 =C2=A0// No knowledg=
e of the existence of class Sub exists here...
<br>>=20
<br>
<br>That's an important point. My (updated) design only allows construc=
tion of deep_ptr from another deep_ptr or using a make_deep_ptr function te=
mplate that (like make_unique) takes constructor arguments. This 'lesse=
r target' will meet my requirements.
<br>
<br>>=20
<br>> So I assume that you shoot for a lesser target, but exactly what i=
s that target and how do you prevent people from trying to use it as in my =
example? How many of the interesting use cases remain if my example doesn&#=
39;t work?
<br>>=20
<br>> My take on this would be to introduce a trait on Base which indica=
tes the name of a virtual method in Base that can be used for cloning. Mayb=
e this is what you indend, but I haven't seen a comprehensible descript=
ion.
<br>>=20
<br>> While small object optimization can be interesting in this scenari=
o I think that is a separate discussion. (it would require a CloneAt(void*,=
Base*) method as well as a ByteCount() method in Base.
<br>>=20
<br>> The problem with the virtual clone method is that it is so easy to=
forget to reimplement it in each subclass. Can anyone come up with a langu=
age feature which automates this?
<br>>=20
<br>> Den fredag 8 januari 2016 kl. 02:14:12 UTC+1 skrev Ville Voutilain=
en:
<br>> On 8 January 2016 at 02:38, Andrew Tomazos <<a>andrew...@gmail.=
com</a>> wrote:=20
<br>> >=20
<br>> >=20
<br>> > On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <<a>jonath...=
@gmail.com</a>> wrote:=20
<br>> >>=20
<br>> >> A deep copying smart pointer that uses type erasure to ca=
ll the copy=20
<br>> >> constructor of derived types would allow the compiler-gen=
erated copy=20
<br>> >> constructor to copy an object composed of polymorphic com=
ponents correctly.=20
<br>> >=20
<br>> >=20
<br>> > Do you mean something like:=20
<br>> >=20
<br>> > std::derived<Animal> animal1 =3D std::make_derived<A=
nimal>(dog)<wbr>; // Dog=20
<br>> > deduced from dog=20
<br>> > std::derived<Animal> animal2 =3D animal1; =C2=A0// call=
s Dog::Dog(const Dog&)=20
<br>> >=20
<br>> > If so, couldn't std::derived<B> be a simple adapter=
around std::any, with=20
<br>> > the added invariant that the contained object be derived from=
B.=20
<br>> >=20
<br>> > Or do I miss something?=20
<br>>=20
<br>>=20
<br>> That would be a different thing. Sean Parent has envisioned an Any=
<T>=20
<br>> almost like that,=20
<br>> but having this thing be a smart pointer allows for certain benefi=
ts,=20
<br>> if we so choose:=20
<br>> - it can always do a noexcept move, even for types that are not mo=
vable=20
<br>> - it doesn't need to clone the incoming value on=20
<br>> construction/assignment, it can just adopt=20
<br>> the pointer=20
<br>> - Any<T> could do it as well, but as opposed to a an actual =
wrapper on any,=20
<br>> it doesn't necessarily need to require CopyConstructible for T=
..=20
<br>>=20
<br>> --=20
<br>>=20
<br>> ---=20
<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 email to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"C5l7YaRBFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;">std-proposal...@<wbr>isocpp.org</a>.
<br>> To post to this group, send email to <a href=3D"javascript:" targe=
t=3D"_blank" gdf-obfuscated-mailto=3D"C5l7YaRBFAAJ" rel=3D"nofollow" onmous=
edown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.hr=
ef=3D'javascript:';return true;">std-pr...@isocpp.org</a>.
<br>> Visit this group at <a href=3D"https://groups.google.com/a/isocpp.=
org/group/std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D=
"this.href=3D'https://groups.google.com/a/isocpp.org/group/std-proposal=
s/';return true;" onclick=3D"this.href=3D'https://groups.google.com=
/a/isocpp.org/group/std-proposals/';return true;">https://groups.google=
..com/a/<wbr>isocpp.org/group/std-<wbr>proposals/</a>.
<br>
<br></blockquote></div></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_483_1608580616.1452253245843--
------=_Part_482_1886001312.1452253245837--
.
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Fri, 8 Jan 2016 11:51:03 +0000
Raw View
My implementation is linked below. Some details are implementation artefact=
s and may not be required.
https://github.com/jbcoe/deep_ptr
I have included tests which make use of the (excellent) catch testing frame=
work. This is included as a submodule.
Jon
> On 8 Jan 2016, at 11:40, Bengt Gustafsson <bengt.gustafsson@beamways.com>=
wrote:
>=20
> That's what I suspected. Only allowing construction with a make_ function=
seems rather restrictive though. The N3339 seems to require an explicit Cl=
oner template parameter to indicate how to clone the pointees. The trait id=
ea could be combined with your make_ function (which we do want anyway for =
consistency) so that IF the trait is defined for a base class of the T clas=
s of the pointer then a reset() function taking a T* is available on the po=
inter. The trait is not to have a default implementation:
>=20
> template<typename T> struct clone_trait;
>=20
>=20
> // Application code to make Base clonable:
>=20
>=20
> template<> struct clone_trait<Base> {
> static Base* clone(const Base* src) { return src->Clone(); } // Ass=
uming Base has a Clone method.
> };
>=20
>=20
>=20
>=20
> Or maybe, to avoid the namespace issues better, an overloadable function =
with a fixed name. I assume your make_ function stores a function pointer t=
o the copy constructor. It should be possible to wrap either this or the tr=
ait method into an object that can be stored in the clone_ptr for future us=
e.
>=20
> Den fredag 8 januari 2016 kl. 12:22:06 UTC+1 skrev Jonathan Coe:
>=20
> > On 8 Jan 2016, at 10:26, Bengt Gustafsson <bengt.gu...@beamways.com> wr=
ote:=20
> >=20
> > I still don't see a solution to the main cloning problem. I read n3339 =
but the "strawman" code was too much to take in, it would be better with a =
very slimmed down version which shows what it can accomplish. I assume that=
we can never get this to work:=20
> >=20
> > class Base {=20
> > };=20
> >=20
> > class Sub : public Base {=20
> > };=20
> >=20
> > Base* b =3D new Sub;=20
> > clone_ptr<Base> p =3D b;=20
> > clone_ptr<Base> p2 =3D p; // No knowledge of the existence of clas=
s Sub exists here...=20
> >=20
>=20
> That's an important point. My (updated) design only allows construction o=
f deep_ptr from another deep_ptr or using a make_deep_ptr function template=
that (like make_unique) takes constructor arguments. This 'lesser target' =
will meet my requirements.=20
>=20
> >=20
> > So I assume that you shoot for a lesser target, but exactly what is tha=
t target and how do you prevent people from trying to use it as in my examp=
le? How many of the interesting use cases remain if my example doesn't work=
?=20
> >=20
> > My take on this would be to introduce a trait on Base which indicates t=
he name of a virtual method in Base that can be used for cloning. Maybe thi=
s is what you indend, but I haven't seen a comprehensible description.=20
> >=20
> > While small object optimization can be interesting in this scenario I t=
hink that is a separate discussion. (it would require a CloneAt(void*, Base=
*) method as well as a ByteCount() method in Base.=20
> >=20
> > The problem with the virtual clone method is that it is so easy to forg=
et to reimplement it in each subclass. Can anyone come up with a language f=
eature which automates this?=20
> >=20
> > Den fredag 8 januari 2016 kl. 02:14:12 UTC+1 skrev Ville Voutilainen:=
=20
> > On 8 January 2016 at 02:38, Andrew Tomazos <andrew...@gmail.com> wrote:=
=20
> > >=20
> > >=20
> > > On Thu, Jan 7, 2016 at 8:51 AM, Jonathan Coe <jonath...@gmail.com> wr=
ote:=20
> > >>=20
> > >> A deep copying smart pointer that uses type erasure to call the copy=
=20
> > >> constructor of derived types would allow the compiler-generated copy=
=20
> > >> constructor to copy an object composed of polymorphic components cor=
rectly.=20
> > >=20
> > >=20
> > > Do you mean something like:=20
> > >=20
> > > std::derived<Animal> animal1 =3D std::make_derived<Animal>(dog); // D=
og=20
> > > deduced from dog=20
> > > std::derived<Animal> animal2 =3D animal1; // calls Dog::Dog(const Do=
g&)=20
> > >=20
> > > If so, couldn't std::derived<B> be a simple adapter around std::any, =
with=20
> > > the added invariant that the contained object be derived from B.=20
> > >=20
> > > Or do I miss something?=20
> >=20
> >=20
> > That would be a different thing. Sean Parent has envisioned an Any<T>=
=20
> > almost like that,=20
> > but having this thing be a smart pointer allows for certain benefits,=
=20
> > if we so choose:=20
> > - it can always do a noexcept move, even for types that are not movable=
=20
> > - it doesn't need to clone the incoming value on=20
> > construction/assignment, it can just adopt=20
> > the pointer=20
> > - Any<T> could do it as well, but as opposed to a an actual wrapper on =
any,=20
> > it doesn't necessarily need to require CopyConstructible for T.=20
> >=20
> > --=20
> >=20
> > ---=20
> > You received this message because you are subscribed to the Google Grou=
ps "ISO C++ Standard - Future Proposals" group.=20
> > To unsubscribe from this group and stop receiving emails from it, send =
an email to std-proposal...@isocpp.org.=20
> > To post to this group, send email to std-pr...@isocpp.org.=20
> > Visit this group at https://groups.google.com/a/isocpp.org/group/std-pr=
oposals/.=20
>=20
>=20
> --=20
>=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=
email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-prop=
osals/.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: "Nevin \":-)\" Liber" <"Nevin ":-)" Liber" <nliber@gmail.com>>
Date: Fri, 8 Jan 2016 08:04:36 -0600
Raw View
--Apple-Mail-73E1EE59-DBA1-4D65-8A1C-EA87FFB4F2C5
Content-Type: text/plain; charset=UTF-8
On Jan 8, 2016, at 4:26 AM, Bengt Gustafsson <bengt.gustafsson@beamways.com> wrote:
>
> I still don't see a solution to the main cloning problem. I read n3339 but the "strawman" code was too much to take in, it would be better with a very slimmed down version which shows what it can accomplish. I assume that we can never get this to work:
>
> class Base {
> };
>
> class Sub : public Base {
> };
>
> Base* b = new Sub;
> clone_ptr<Base> p = b;
> clone_ptr<Base> p2 = p; // No knowledge of the existence of
Doesn't shared_ptr suffer from the same issue? Seems okay in practice.
--
>
> Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-312-623-5420
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--Apple-Mail-73E1EE59-DBA1-4D65-8A1C-EA87FFB4F2C5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div>On Jan 8, 2016, at 4:26 AM, Bengt =
Gustafsson <<a href=3D"mailto:bengt.gustafsson@beamways.com">bengt.gusta=
fsson@beamways.com</a>> wrote:</div><div><br></div><blockquote type=3D"c=
ite"><div>I still don't see a solution to the main cloning problem. I read =
n3339 but the "strawman" code was too much to take in, it would be better w=
ith a very slimmed down version which shows what it can accomplish. I assum=
e that we can never get this to work:</div><div><br></div><div class=3D"pre=
ttyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-w=
ord; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Base=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Sub</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">public</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Base</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br><br></span><span style=3D"color: #606;" class=3D"styled-by-pr=
ettify">Base</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">new</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">Sub</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>clone_ptr</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">Base</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
p </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>clone_ptr</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Base</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> p2 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> p</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #800;" class=3D"styled-by=
-prettify">// No knowledge of the existence of </span></div></code></div></=
blockquote><span style=3D"background-color: rgba(255, 255, 255, 0);"><br>Do=
esn't shared_ptr suffer from the same issue? Seems okay in practice.&=
nbsp;<br>-- </span><blockquote type=3D"cite"><div class=3D"prettyprint=
" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span class=3D"styl=
ed-by-prettify" style=3D"background-color: rgba(255, 255, 255, 0);"><font c=
olor=3D"#000000" face=3D"UICTFontTextStyleBody"> Nevin ":-)" Liber <=
;<a href=3D"mailto:nevin@eviloverlord.com">mailto:nevin@eviloverlord.com</a=
>> +1-312-623-5420</font></span></div></code></div><div></div></bl=
ockquote></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail-73E1EE59-DBA1-4D65-8A1C-EA87FFB4F2C5--
.
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Fri, 8 Jan 2016 14:43:24 +0000
Raw View
--Apple-Mail-69BC9DBC-83CD-4876-A875-AC4CA3B6CBA7
Content-Type: text/plain; charset=UTF-8
A similar issue with shared_ptr can be saved by virtual destructors.
I'm not proposing that we add virtual copy constructors.
Jon
> On 8 Jan 2016, at 14:04, "Nevin \":-)\" Liber" <"Nevin ":-)" Liber" <nliber@gmail.com>> <nliber@gmail.com> wrote:
>
>> On Jan 8, 2016, at 4:26 AM, Bengt Gustafsson <bengt.gustafsson@beamways.com> wrote:
>>
>> I still don't see a solution to the main cloning problem. I read n3339 but the "strawman" code was too much to take in, it would be better with a very slimmed down version which shows what it can accomplish. I assume that we can never get this to work:
>>
>> class Base {
>> };
>>
>> class Sub : public Base {
>> };
>>
>> Base* b = new Sub;
>> clone_ptr<Base> p = b;
>> clone_ptr<Base> p2 = p; // No knowledge of the existence of
>
> Doesn't shared_ptr suffer from the same issue? Seems okay in practice.
> --
>>
>> Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-312-623-5420
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--Apple-Mail-69BC9DBC-83CD-4876-A875-AC4CA3B6CBA7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div></div><div>A similar issue with sh=
ared_ptr can be saved by virtual destructors. </div><div><br></div><di=
v>I'm not proposing that we add virtual copy constructors.</div><div><br></=
div><div>Jon</div><div><br>On 8 Jan 2016, at 14:04, "Nevin \":-)\" Liber" &=
lt;"Nevin ":-)" Liber" <<a href=3D"mailto:nliber@gmail.com">nliber@gmail=
..com</a>>> <<a href=3D"mailto:nliber@gmail.com">nliber@gmail.com</=
a>> wrote:<br><br></div><blockquote type=3D"cite"><div><meta http-equiv=
=3D"content-type" content=3D"text/html; charset=3Dutf-8"><div>On Jan 8, 201=
6, at 4:26 AM, Bengt Gustafsson <<a href=3D"mailto:bengt.gustafsson@beam=
ways.com">bengt.gustafsson@beamways.com</a>> wrote:</div><div><br></div>=
<blockquote type=3D"cite"><div>I still don't see a solution to the main clo=
ning problem. I read n3339 but the "strawman" code was too much to take in,=
it would be better with a very slimmed down version which shows what it ca=
n accomplish. I assume that we can never get this to work:</div><div><br></=
div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187=
); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Base</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Sub</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">public</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Base</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Base</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> b </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">new</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Sub</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>clone_ptr</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">Base</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> p </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>clone_p=
tr</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</sp=
an><span style=3D"color: #606;" class=3D"styled-by-prettify">Base</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">></span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> p2 </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> p</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #800;"=
class=3D"styled-by-prettify">// No knowledge of the existence of </span></=
div></code></div></blockquote><span style=3D"background-color: rgba(255, 25=
5, 255, 0);"><br>Doesn't shared_ptr suffer from the same issue? Seems=
okay in practice. <br>-- </span><blockquote type=3D"cite"><div c=
lass=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wr=
ap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span class=3D"styled-by-prettify" style=3D"background-color: rgba(255, 255=
, 255, 0);"><font color=3D"#000000" face=3D"UICTFontTextStyleBody"> Ne=
vin ":-)" Liber <<a href=3D"mailto:nevin@eviloverlord.com">mailto:nevin@=
eviloverlord.com</a>> +1-312-623-5420</font></span></div></code></=
div><div></div></blockquote>
<p></p>
-- <br>
<br>
--- <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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br>
</div></blockquote></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail-69BC9DBC-83CD-4876-A875-AC4CA3B6CBA7--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 8 Jan 2016 12:17:08 -0800 (PST)
Raw View
------=_Part_1121_144758099.1452284229111
Content-Type: text/plain; charset=UTF-8
Nevin: The deep_ptr is supposed to clone the pointee which the shared_ptr never does. That's the problem here: How can the exact subclass of the pointee be known at the later time when the cloning is to take place.
Many other languages support the eqivalent of a virtual copy ctor, and it would be simple to add to C++. Of course it would be totally nonlogical to allow virtual on exactly the copy ctor but in practice it would feel right, I think.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1121_144758099.1452284229111--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 8 Jan 2016 22:25:54 +0200
Raw View
On 8 January 2016 at 22:17, Bengt Gustafsson
<bengt.gustafsson@beamways.com> wrote:
> Nevin: The deep_ptr is supposed to clone the pointee which the shared_ptr never does. That's the problem here: How can the exact subclass of the pointee be known at the later time when the cloning is to take place.
>
> Many other languages support the eqivalent of a virtual copy ctor, and it would be simple to add to C++. Of course it would be totally nonlogical to allow virtual on exactly the copy ctor but in practice it would feel right, I think.
If you have a type hierarchy that can do polymorphic copies (via a
virtual clone() or some such), then
you can make it work. Other than that, the issue is exactly the same
as with shared_ptr, even though
shared_ptr doesn't clone. To explain how it's exactly the same issue
with shared_ptr, consider:
struct B {}; // note, no virtual destructor
struct D : B {~D();};
int main()
{
shared_ptr<B> b{new D()}; // this works fine
B* b2 = new D();
shared_ptr<B> b3{b2}; // this doesn't work
}
It's not an issue with cloning. It's an issue with type erasure. If
you create a cloned_ptr<B>
from a B*, all knowledge of the fact that the B* was actually really a
D* has been lost already.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 8 Jan 2016 15:31:32 -0800 (PST)
Raw View
------=_Part_1392_436561775.1452295893010
Content-Type: multipart/alternative;
boundary="----=_Part_1393_822385452.1452295893076"
------=_Part_1393_822385452.1452295893076
Content-Type: text/plain; charset=UTF-8
Of course, but it is stlil a big difference in that you can easily add a
virtual destructor to the baseclass and then it will automatically work for
all subclasses. If you just adhere to this shuffling around the pointee
between different shared_ptr instances is ok. And it was my bad not to
include a virtual destructor in my example. What I wanted to show was that
cloning could never work even with this in place (just as you remarked).
As for your shared_ptr example (as an aside), wouldn't it be nice to be
able to flag that using a trait has_virtual_dtor<T> (needed on both types
when doing a cross-type assignment between shared_ptrs). I guess this could
break some code, but more often would reveal bugs not hitherto detected...
After reading Jonathans implementation I doubt that this can even work for
the multiple-inheritance case. I don't mean just his code but in general:
The U* inside the inner<U> object gets properly cast after the first copy
operation, but after the second copying it wont, as the creation of the
third inner object gets the template parameter of the second, not the
first. It's late now and I may not be thinking straight, but at this point
I think it is impossible (for multiple inheritance) without help from the
pointee.
Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:
>
> On 8 January 2016 at 22:17, Bengt Gustafsson
> <bengt.gu...@beamways.com <javascript:>> wrote:
> > Nevin: The deep_ptr is supposed to clone the pointee which the
> shared_ptr never does. That's the problem here: How can the exact subclass
> of the pointee be known at the later time when the cloning is to take
> place.
> >
> > Many other languages support the eqivalent of a virtual copy ctor, and
> it would be simple to add to C++. Of course it would be totally nonlogical
> to allow virtual on exactly the copy ctor but in practice it would feel
> right, I think.
>
>
> If you have a type hierarchy that can do polymorphic copies (via a
> virtual clone() or some such), then
> you can make it work. Other than that, the issue is exactly the same
> as with shared_ptr, even though
> shared_ptr doesn't clone. To explain how it's exactly the same issue
> with shared_ptr, consider:
>
> struct B {}; // note, no virtual destructor
> struct D : B {~D();};
>
> int main()
> {
> shared_ptr<B> b{new D()}; // this works fine
> B* b2 = new D();
> shared_ptr<B> b3{b2}; // this doesn't work
> }
>
> It's not an issue with cloning. It's an issue with type erasure. If
> you create a cloned_ptr<B>
> from a B*, all knowledge of the fact that the B* was actually really a
> D* has been lost already.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1393_822385452.1452295893076
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Of course, but it is stlil a big difference in that you ca=
n easily add a virtual destructor to the baseclass and then it will automat=
ically work for all subclasses. If you just adhere to this shuffling around=
the pointee between different shared_ptr instances is ok. And it was my ba=
d not to include a virtual destructor in my example. What I wanted to show =
was that cloning could never work even with this in place (just as you rema=
rked).<div><br></div><div>As for your shared_ptr example (as an aside), wou=
ldn't it be nice to be able to flag that using a trait has_virtual_dtor=
<T> (needed on both types when doing a cross-type assignment between =
shared_ptrs). I guess this could break some code, but more often would reve=
al bugs not hitherto detected...<br><div><br><div>After reading Jonathans i=
mplementation I doubt that this can even work for the multiple-inheritance =
case. I don't mean just his code but in general: The U* inside the inne=
r<U> object gets properly cast after the first copy operation, but af=
ter the second copying it wont, as the creation of the third inner object g=
ets the template parameter of the second, not the first. It's late now =
and I may not be thinking straight, but at this point I think it is impossi=
ble (for multiple inheritance) without help from the pointee.</div><div><br=
><br>Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">On 8 January 2016 at 22:17, Ben=
gt Gustafsson
<br><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
lyPN61FfFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">bengt.gu...@beamways.com</a><wbr>> wrote:
<br>> Nevin: The deep_ptr is supposed to clone the pointee which the sha=
red_ptr never does. That's the problem here: How can the exact subclass=
of the pointee be known at the later time when the cloning is to take plac=
e.
<br>>
<br>> Many other languages support the eqivalent of a virtual copy ctor,=
and it would be simple to add to C++. Of course it would be totally nonlog=
ical to allow virtual on exactly the copy ctor but in practice it would fee=
l right, I think.
<br>
<br>
<br>If you have a type hierarchy that can do polymorphic copies (via a
<br>virtual clone() or some such), then
<br>you can make it work. Other than that, the issue is exactly the same
<br>as with shared_ptr, even though
<br>shared_ptr doesn't clone. To explain how it's exactly the same =
issue
<br>with shared_ptr, consider:
<br>
<br>struct B {}; =C2=A0// note, no virtual destructor
<br>struct D : B {~D();};
<br>
<br>int main()
<br>{
<br>=C2=A0 =C2=A0 shared_ptr<B> b{new D()}; // this works fine
<br>=C2=A0 =C2=A0 B* b2 =3D new D();
<br>=C2=A0 =C2=A0 shared_ptr<B> b3{b2}; // this doesn't work
<br>}
<br>
<br>It's not an issue with cloning. It's an issue with type erasure=
.. If
<br>you create a cloned_ptr<B>
<br>from a B*, all knowledge of the fact that the B* was actually really a
<br>D* has been lost already.
<br></blockquote></div></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1393_822385452.1452295893076--
------=_Part_1392_436561775.1452295893010--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 8 Jan 2016 15:37:43 -0800 (PST)
Raw View
------=_Part_1147_1875165781.1452296263567
Content-Type: multipart/alternative;
boundary="----=_Part_1148_487261440.1452296263568"
------=_Part_1148_487261440.1452296263568
Content-Type: text/plain; charset=UTF-8
By the way, not even your first construction works, Ville, unless there is
some magic I didn't know of in shared_ptr. Doesn't it just do "delete _ptr"
in the last destructor? At least cppreference.com does not mention anything
more advanced:
http://en.cppreference.com/w/cpp/memory/shared_ptr
They refer to "delete expression" which links to the page for "delete
_ptr"...
Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:
>
> On 8 January 2016 at 22:17, Bengt Gustafsson
> <bengt.gu...@beamways.com <javascript:>> wrote:
> > Nevin: The deep_ptr is supposed to clone the pointee which the
> shared_ptr never does. That's the problem here: How can the exact subclass
> of the pointee be known at the later time when the cloning is to take
> place.
> >
> > Many other languages support the eqivalent of a virtual copy ctor, and
> it would be simple to add to C++. Of course it would be totally nonlogical
> to allow virtual on exactly the copy ctor but in practice it would feel
> right, I think.
>
>
> If you have a type hierarchy that can do polymorphic copies (via a
> virtual clone() or some such), then
> you can make it work. Other than that, the issue is exactly the same
> as with shared_ptr, even though
> shared_ptr doesn't clone. To explain how it's exactly the same issue
> with shared_ptr, consider:
>
> struct B {}; // note, no virtual destructor
> struct D : B {~D();};
>
> int main()
> {
> shared_ptr<B> b{new D()}; // this works fine
> B* b2 = new D();
> shared_ptr<B> b3{b2}; // this doesn't work
> }
>
> It's not an issue with cloning. It's an issue with type erasure. If
> you create a cloned_ptr<B>
> from a B*, all knowledge of the fact that the B* was actually really a
> D* has been lost already.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1148_487261440.1452296263568
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">By the way, not even your first construction works, Ville,=
unless there is some magic I didn't know of in shared_ptr. Doesn't=
it just do "delete _ptr" in the last destructor? At least cppref=
erence.com does not mention anything more advanced:<div><br></div><div>http=
://en.cppreference.com/w/cpp/memory/shared_ptr</div><div><br></div><div>The=
y refer to "delete expression" which links to the page for "=
delete _ptr"...</div><div><br><br>Den fredag 8 januari 2016 kl. 21:25:=
57 UTC+1 skrev Ville Voutilainen:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">On 8 January 2016 at 22:17, Bengt Gustafsson
<br><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
lyPN61FfFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">bengt.gu...@beamways.com</a><wbr>> wrote:
<br>> Nevin: The deep_ptr is supposed to clone the pointee which the sha=
red_ptr never does. That's the problem here: How can the exact subclass=
of the pointee be known at the later time when the cloning is to take plac=
e.
<br>>
<br>> Many other languages support the eqivalent of a virtual copy ctor,=
and it would be simple to add to C++. Of course it would be totally nonlog=
ical to allow virtual on exactly the copy ctor but in practice it would fee=
l right, I think.
<br>
<br>
<br>If you have a type hierarchy that can do polymorphic copies (via a
<br>virtual clone() or some such), then
<br>you can make it work. Other than that, the issue is exactly the same
<br>as with shared_ptr, even though
<br>shared_ptr doesn't clone. To explain how it's exactly the same =
issue
<br>with shared_ptr, consider:
<br>
<br>struct B {}; =C2=A0// note, no virtual destructor
<br>struct D : B {~D();};
<br>
<br>int main()
<br>{
<br>=C2=A0 =C2=A0 shared_ptr<B> b{new D()}; // this works fine
<br>=C2=A0 =C2=A0 B* b2 =3D new D();
<br>=C2=A0 =C2=A0 shared_ptr<B> b3{b2}; // this doesn't work
<br>}
<br>
<br>It's not an issue with cloning. It's an issue with type erasure=
.. If
<br>you create a cloned_ptr<B>
<br>from a B*, all knowledge of the fact that the B* was actually really a
<br>D* has been lost already.
<br></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1148_487261440.1452296263568--
------=_Part_1147_1875165781.1452296263567--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 01:54:37 +0200
Raw View
On 9 January 2016 at 01:31, Bengt Gustafsson
<bengt.gustafsson@beamways.com> wrote:
> Of course, but it is stlil a big difference in that you can easily add a
> virtual destructor to the baseclass and then it will automatically work for
> all subclasses. If you just adhere to this shuffling around the pointee
> between different shared_ptr instances is ok. And it was my bad not to
> include a virtual destructor in my example. What I wanted to show was that
> cloning could never work even with this in place (just as you remarked).
Cloning works fine if you give a cloned_ptr<B> a D* instead of a B*. If you want
to make cloning work when you give a cloned_ptr<B> a B*, you must also provide
a custom cloner that can clone via a B*, using a virtual clone() or
some such facility.
I don't see why we should try to perform further magic in cloned_ptr
to solve this problem.
>
> As for your shared_ptr example (as an aside), wouldn't it be nice to be able
> to flag that using a trait has_virtual_dtor<T> (needed on both types when
> doing a cross-type assignment between shared_ptrs). I guess this could break
> some code, but more often would reveal bugs not hitherto detected...
That breaks existing code that uses shared_ptr with hierarchies without virtual
destructors, and that code works just fine. It also seemingly breaks
shared_ptr<void>
being a universal wrapper for any type.
> After reading Jonathans implementation I doubt that this can even work for
> the multiple-inheritance case. I don't mean just his code but in general:
> The U* inside the inner<U> object gets properly cast after the first copy
> operation, but after the second copying it wont, as the creation of the
> third inner object gets the template parameter of the second, not the first.
> It's late now and I may not be thinking straight, but at this point I think
> it is impossible (for multiple inheritance) without help from the pointee.
I haven't looked at his implementation in such detail, but the implementation
I have retains the original type identity in the original cloner,
which gets cloned as well,
so multiple copies don't break it. That's one of the reasons I wanted
to pursue a
type-erasing deep-copying smart pointer to begin with; doing it
without type erasure
makes it freakishly hard to do the right thing across multiple copies.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 01:56:14 +0200
Raw View
On 9 January 2016 at 01:37, Bengt Gustafsson
<bengt.gustafsson@beamways.com> wrote:
> By the way, not even your first construction works, Ville, unless there is
> some magic I didn't know of in shared_ptr. Doesn't it just do "delete _ptr"
There's no "magic". It invokes the operator() of a default_delete<D>,
which does the right
thing. The incoming deleter (which is defaulted) is type-erased and
invoked indirectly.
The "first construction" I wrote absolutely works, and that's how it's
specified.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Fri, 8 Jan 2016 23:58:05 +0000
Raw View
--047d7b6d9fb6c1be870528db5b5c
Content-Type: text/plain; charset=UTF-8
On 8 January 2016 at 23:31, Bengt Gustafsson <bengt.gustafsson@beamways.com>
wrote:
> Of course, but it is stlil a big difference in that you can easily add a
> virtual destructor to the baseclass and then it will automatically work for
> all subclasses. If you just adhere to this shuffling around the pointee
> between different shared_ptr instances is ok. And it was my bad not to
> include a virtual destructor in my example. What I wanted to show was that
> cloning could never work even with this in place (just as you remarked).
>
> As for your shared_ptr example (as an aside), wouldn't it be nice to be
> able to flag that using a trait has_virtual_dtor<T> (needed on both types
> when doing a cross-type assignment between shared_ptrs). I guess this could
> break some code, but more often would reveal bugs not hitherto detected...
>
> After reading Jonathans implementation I doubt that this can even work for
> the multiple-inheritance case. I don't mean just his code but in general:
> The U* inside the inner<U> object gets properly cast after the first copy
> operation, but after the second copying it wont, as the creation of the
> third inner object gets the template parameter of the second, not the
> first. It's late now and I may not be thinking straight, but at this point
> I think it is impossible (for multiple inheritance) without help from the
> pointee.
>
>
If construction is only possible through a factory method, then the static
type and dynamic type of the object must be the same.
To clarify, your earlier example was of a pointer whose dynamic type
differed from the static type used in the pointer constructor.
1 Base* b = new Sub;
2 clone_ptr<Base> p = b;
3 clone_ptr<Base> p2 = p;
I do not allow assignment or construction from raw pointers, only from
deep_ptrs (clone_ptrs) so line 2 will not compile.
I don't see how multiple inheritance complicates this, can you elaborate?
>
> Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:
>>
>> On 8 January 2016 at 22:17, Bengt Gustafsson
>> <bengt.gu...@beamways.com> wrote:
>> > Nevin: The deep_ptr is supposed to clone the pointee which the
>> shared_ptr never does. That's the problem here: How can the exact subclass
>> of the pointee be known at the later time when the cloning is to take
>> place.
>> >
>> > Many other languages support the eqivalent of a virtual copy ctor, and
>> it would be simple to add to C++. Of course it would be totally nonlogical
>> to allow virtual on exactly the copy ctor but in practice it would feel
>> right, I think.
>>
>>
>> If you have a type hierarchy that can do polymorphic copies (via a
>> virtual clone() or some such), then
>> you can make it work. Other than that, the issue is exactly the same
>> as with shared_ptr, even though
>> shared_ptr doesn't clone. To explain how it's exactly the same issue
>> with shared_ptr, consider:
>>
>> struct B {}; // note, no virtual destructor
>> struct D : B {~D();};
>>
>> int main()
>> {
>> shared_ptr<B> b{new D()}; // this works fine
>> B* b2 = new D();
>> shared_ptr<B> b3{b2}; // this doesn't work
>> }
>>
>> It's not an issue with cloning. It's an issue with type erasure. If
>> you create a cloned_ptr<B>
>> from a B*, all knowledge of the fact that the B* was actually really a
>> D* has been lost already.
>>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b6d9fb6c1be870528db5b5c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On 8 January 2016 at 23:31, Bengt Gustafsson <span dir=3D"ltr"><<a h=
ref=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustaf=
sson@beamways.com</a>></span> wrote:<br><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-left-style:solid;padding-left:1ex"><div dir=3D"ltr=
">Of course, but it is stlil a big difference in that you can easily add a =
virtual destructor to the baseclass and then it will automatically work for=
all subclasses. If you just adhere to this shuffling around the pointee be=
tween different shared_ptr instances is ok. And it was my bad not to includ=
e a virtual destructor in my example. What I wanted to show was that clonin=
g could never work even with this in place (just as you remarked).<div><br>=
</div><div>As for your shared_ptr example (as an aside), wouldn't it be=
nice to be able to flag that using a trait has_virtual_dtor<T> (need=
ed on both types when doing a cross-type assignment between shared_ptrs). I=
guess this could break some code, but more often would reveal bugs not hit=
herto detected...<br><div><br><div>After reading Jonathans implementation I=
doubt that this can even work for the multiple-inheritance case. I don'=
;t mean just his code but in general: The U* inside the inner<U> obje=
ct gets properly cast after the first copy operation, but after the second =
copying it wont, as the creation of the third inner object gets the templat=
e parameter of the second, not the first. It's late now and I may not b=
e thinking straight, but at this point I think it is impossible (for multip=
le inheritance) without help from the pointee.</div><div><span class=3D""><=
br></span></div></div></div></div></blockquote><div><br></div><div>If const=
ruction is only possible through a factory method, then the static type and=
dynamic type of the object must be the same.=C2=A0</div><div><br></div><di=
v>To clarify, your earlier example was of a pointer whose dynamic type diff=
ered from the static type used in the pointer constructor.</div><div><br></=
div><div><span style=3D"font-family:monospace;font-size:10px;color:rgb(102,=
0,102)">1 Base</span><span style=3D"font-family:monospace;font-size:10px;co=
lor:rgb(102,102,0)">*</span><span style=3D"font-family:monospace;font-size:=
10px;color:rgb(0,0,0)">=C2=A0b=C2=A0</span><span style=3D"font-family:monos=
pace;font-size:10px;color:rgb(102,102,0)">=3D</span><span style=3D"font-fam=
ily:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0</span><span style=3D"=
font-family:monospace;font-size:10px;color:rgb(0,0,136)">new</span><span st=
yle=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0</span>=
<span style=3D"font-family:monospace;font-size:10px;color:rgb(102,0,102)">S=
ub</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(102,=
102,0)">;</span><span style=3D"font-family:monospace;font-size:10px;color:r=
gb(0,0,0)"><br>2 clone_ptr</span><span style=3D"font-family:monospace;font-=
size:10px;color:rgb(102,102,0)"><</span><span style=3D"font-family:monos=
pace;font-size:10px;color:rgb(102,0,102)">Base</span><span style=3D"font-fa=
mily:monospace;font-size:10px;color:rgb(102,102,0)">></span><span style=
=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0p=C2=A0</s=
pan><span style=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0=
)">=3D</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(=
0,0,0)">=C2=A0b</span><span style=3D"font-family:monospace;font-size:10px;c=
olor:rgb(102,102,0)">;</span><span style=3D"font-family:monospace;font-size=
:10px;color:rgb(0,0,0)"><br>3 clone_ptr</span><span style=3D"font-family:mo=
nospace;font-size:10px;color:rgb(102,102,0)"><</span><span style=3D"font=
-family:monospace;font-size:10px;color:rgb(102,0,102)">Base</span><span sty=
le=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)">></span=
><span style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=
=A0p2=C2=A0</span><span style=3D"font-family:monospace;font-size:10px;color=
:rgb(102,102,0)">=3D</span><span style=3D"font-family:monospace;font-size:1=
0px;color:rgb(0,0,0)">=C2=A0p</span><span style=3D"font-family:monospace;fo=
nt-size:10px;color:rgb(102,102,0)">;</span><span style=3D"font-family:monos=
pace;font-size:10px;color:rgb(0,0,0)">=C2=A0=C2=A0</span><br></div><div><br=
></div><div>I do not allow assignment or construction from raw pointers, on=
ly from deep_ptrs (clone_ptrs) so line 2 will not compile.</div><div><br></=
div><div>I don't see how multiple inheritance complicates this, can you=
elaborate?<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(=
204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><di=
v><div><div><span class=3D""><br>Den fredag 8 januari 2016 kl. 21:25:57 UTC=
+1 skrev Ville Voutilainen:</span><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><span class=3D"">On 8 =
January 2016 at 22:17, Bengt Gustafsson
<br></span><div><div class=3D"h5"><<a rel=3D"nofollow">bengt.gu...@beamw=
ays.com</a>> wrote:
<br>> Nevin: The deep_ptr is supposed to clone the pointee which the sha=
red_ptr never does. That's the problem here: How can the exact subclass=
of the pointee be known at the later time when the cloning is to take plac=
e.
<br>>
<br>> Many other languages support the eqivalent of a virtual copy ctor,=
and it would be simple to add to C++. Of course it would be totally nonlog=
ical to allow virtual on exactly the copy ctor but in practice it would fee=
l right, I think.
<br>
<br>
<br>If you have a type hierarchy that can do polymorphic copies (via a
<br>virtual clone() or some such), then
<br>you can make it work. Other than that, the issue is exactly the same
<br>as with shared_ptr, even though
<br>shared_ptr doesn't clone. To explain how it's exactly the same =
issue
<br>with shared_ptr, consider:
<br>
<br>struct B {}; =C2=A0// note, no virtual destructor
<br>struct D : B {~D();};
<br>
<br>int main()
<br>{
<br>=C2=A0 =C2=A0 shared_ptr<B> b{new D()}; // this works fine
<br>=C2=A0 =C2=A0 B* b2 =3D new D();
<br>=C2=A0 =C2=A0 shared_ptr<B> b3{b2}; // this doesn't work
<br>}
<br>
<br>It's not an issue with cloning. It's an issue with type erasure=
.. If
<br>you create a cloned_ptr<B>
<br>from a B*, all knowledge of the fact that the B* was actually really a
<br>D* has been lost already.
<br></div></div></blockquote></div></div></div></div><div class=3D""><div c=
lass=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7b6d9fb6c1be870528db5b5c--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 02:07:22 +0200
Raw View
On 9 January 2016 at 01:56, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 9 January 2016 at 01:37, Bengt Gustafsson
> <bengt.gustafsson@beamways.com> wrote:
>> By the way, not even your first construction works, Ville, unless there is
>> some magic I didn't know of in shared_ptr. Doesn't it just do "delete _ptr"
>
> There's no "magic". It invokes the operator() of a default_delete<D>,
> which does the right
> thing. The incoming deleter (which is defaulted) is type-erased and
> invoked indirectly.
> The "first construction" I wrote absolutely works, and that's how it's
> specified.
Ah, I see that the specification is not so easy to read. The constructor used
is the templated one, which takes a Y* p. Cryptic specification aside,
shared_ptr
will destroy it by doing a delete p (or the as-if-equivalent of that
expression), which
means it will destroy a Y*, not a T*. Hence there's no requirement for a virtual
destructor and the code works as expected.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 02:08:25 +0200
Raw View
On 9 January 2016 at 01:58, Jonathan Coe <jbcoe@me.com> wrote:
> If construction is only possible through a factory method, then the static
> type and dynamic type of the object must be the same.
Seems draconian, and there's also .reset().
> To clarify, your earlier example was of a pointer whose dynamic type
> differed from the static type used in the pointer constructor.
>
> 1 Base* b = new Sub;
> 2 clone_ptr<Base> p = b;
> 3 clone_ptr<Base> p2 = p;
>
> I do not allow assignment or construction from raw pointers, only from
> deep_ptrs (clone_ptrs) so line 2 will not compile.
You do not allow construction from raw pointers? :) Surely that's not the case.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sat, 9 Jan 2016 00:12:06 +0000
Raw View
--001a114971a2daef6d0528db8d04
Content-Type: text/plain; charset=UTF-8
I can't see how to ensure that the deep copy is correct unless the static
and dynamic types of the pointer can be guaranteed to be equal at compile
time.
It seems necessary and meets my (rather simple) requirements.
Jon
On 9 January 2016 at 00:08, Ville Voutilainen <ville.voutilainen@gmail.com>
wrote:
> On 9 January 2016 at 01:58, Jonathan Coe <jbcoe@me.com> wrote:
> > If construction is only possible through a factory method, then the
> static
> > type and dynamic type of the object must be the same.
>
> Seems draconian, and there's also .reset().
>
> > To clarify, your earlier example was of a pointer whose dynamic type
> > differed from the static type used in the pointer constructor.
> >
> > 1 Base* b = new Sub;
> > 2 clone_ptr<Base> p = b;
> > 3 clone_ptr<Base> p2 = p;
> >
> > I do not allow assignment or construction from raw pointers, only from
> > deep_ptrs (clone_ptrs) so line 2 will not compile.
>
> You do not allow construction from raw pointers? :) Surely that's not the
> case.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a114971a2daef6d0528db8d04
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I can't see how to ensure that the deep copy is correc=
t unless the static and dynamic types of the pointer can be guaranteed to b=
e equal at compile time.<div><br></div><div>It seems necessary and meets my=
(rather simple) requirements.</div><div><br></div><div>Jon</div></div><div=
class=3D"gmail_extra"><br><div class=3D"gmail_quote">On 9 January 2016 at =
00:08, Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto:ville.vout=
ilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com</a>></s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On 9 January=
2016 at 01:58, Jonathan Coe <<a href=3D"mailto:jbcoe@me.com">jbcoe@me.c=
om</a>> wrote:<br>
> If construction is only possible through a factory method, then the st=
atic<br>
> type and dynamic type of the object must be the same.<br>
<br>
</span>Seems draconian, and there's also .reset().<br>
<span class=3D""><br>
> To clarify, your earlier example was of a pointer whose dynamic type<b=
r>
> differed from the static type used in the pointer constructor.<br>
><br>
> 1 Base* b =3D new Sub;<br>
> 2 clone_ptr<Base> p =3D b;<br>
> 3 clone_ptr<Base> p2 =3D p;<br>
><br>
> I do not allow assignment or construction from raw pointers, only from=
<br>
> deep_ptrs (clone_ptrs) so line 2 will not compile.<br>
<br>
</span>You do not allow construction from raw pointers? :) Surely that'=
s not the case.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a114971a2daef6d0528db8d04--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 02:20:48 +0200
Raw View
On 9 January 2016 at 02:12, Jonathan Coe <jbcoe@me.com> wrote:
> I can't see how to ensure that the deep copy is correct unless the static
> and dynamic types of the pointer can be guaranteed to be equal at compile
> time.
>
> It seems necessary and meets my (rather simple) requirements.
Huh? You seem to be saying that a cloned_ptr<B> can't construct from a D*.
Or that a cloned_ptr<void> can't construct from anything. The deep copy can be
made perfectly correct in those cases just like the "deep destruction" can be
made safe in shared_ptr; via a constructor template, construct a cloner that
clones and destroys a D*, not a B*, erase its type and store it.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sat, 9 Jan 2016 00:24:34 +0000
Raw View
--001a1143e5ba7046f40528dbba76
Content-Type: text/plain; charset=UTF-8
I agree that it can be made safe but it cannot be guaranteed to be safe.
I'm looking for stricter requirements than shared_ptr's destructor as I
cannot make the problem go away by introducing virtual copy constructors.
Any 'issues' with shared_ptr can be fixed with the introduction of virtual
destructors.
Jon
On 9 January 2016 at 00:20, Ville Voutilainen <ville.voutilainen@gmail.com>
wrote:
> On 9 January 2016 at 02:12, Jonathan Coe <jbcoe@me.com> wrote:
> > I can't see how to ensure that the deep copy is correct unless the static
> > and dynamic types of the pointer can be guaranteed to be equal at compile
> > time.
> >
> > It seems necessary and meets my (rather simple) requirements.
>
> Huh? You seem to be saying that a cloned_ptr<B> can't construct from a D*.
> Or that a cloned_ptr<void> can't construct from anything. The deep copy
> can be
> made perfectly correct in those cases just like the "deep destruction" can
> be
> made safe in shared_ptr; via a constructor template, construct a cloner
> that
> clones and destroys a D*, not a B*, erase its type and store it.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a1143e5ba7046f40528dbba76
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I agree that it can be made safe but it cannot be guarante=
ed to be safe.<div><br></div><div>I'm looking for stricter requirements=
than shared_ptr's destructor as I cannot make the problem go away by i=
ntroducing virtual copy constructors. Any 'issues' with shared_ptr =
can be fixed with the introduction of virtual destructors.</div><div><br></=
div><div>Jon</div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_=
quote">On 9 January 2016 at 00:20, Ville Voutilainen <span dir=3D"ltr"><=
<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">ville.vout=
ilainen@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"><=
span class=3D"">On 9 January 2016 at 02:12, Jonathan Coe <<a href=3D"mai=
lto:jbcoe@me.com">jbcoe@me.com</a>> wrote:<br>
> I can't see how to ensure that the deep copy is correct unless the=
static<br>
> and dynamic types of the pointer can be guaranteed to be equal at comp=
ile<br>
> time.<br>
><br>
> It seems necessary and meets my (rather simple) requirements.<br>
<br>
</span>Huh? You seem to be saying that a cloned_ptr<B> can't cons=
truct from a D*.<br>
Or that a cloned_ptr<void> can't construct from anything. The dee=
p copy can be<br>
made perfectly correct in those cases just like the "deep destruction&=
quot; can be<br>
made safe in shared_ptr; via a constructor template, construct a cloner tha=
t<br>
clones and destroys a D*, not a B*, erase its type and store it.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a1143e5ba7046f40528dbba76--
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sat, 9 Jan 2016 00:29:48 +0000
Raw View
--001a1143ebec2bf6fa0528dbcdf4
Content-Type: text/plain; charset=UTF-8
On 9 January 2016 at 00:20, Ville Voutilainen <ville.voutilainen@gmail.com>
wrote:
> On 9 January 2016 at 02:12, Jonathan Coe <jbcoe@me.com> wrote:
> > I can't see how to ensure that the deep copy is correct unless the static
> > and dynamic types of the pointer can be guaranteed to be equal at compile
> > time.
> >
> > It seems necessary and meets my (rather simple) requirements.
>
> Huh? You seem to be saying that a cloned_ptr<B> can't construct from a D*.
> Or that a cloned_ptr<void> can't construct from anything. The deep copy
> can be
> made perfectly correct in those cases just like the "deep destruction" can
> be
> made safe in shared_ptr; via a constructor template, construct a cloner
> that
> clones and destroys a D*, not a B*, erase its type and store it.
>
>
The potential issue here is that the D* points to a further derived DD*. If
I copy it as a D I will slice it and do the wrong thing.
I need to know the dynamic type of a pointer to copy the pointee correctly.
(apologies for earlier top post. GMail makes it very easy to do.)
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a1143ebec2bf6fa0528dbcdf4
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 9 January 2016 at 00:20, Ville Voutilainen <span dir=3D=
"ltr"><<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">=
ville.voutilainen@gmail.com</a>></span> wrote:<br><div class=3D"gmail_ex=
tra"><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"><span class=
=3D"">On 9 January 2016 at 02:12, Jonathan Coe <<a href=3D"mailto:jbcoe@=
me.com">jbcoe@me.com</a>> wrote:<br>
> I can't see how to ensure that the deep copy is correct unless the=
static<br>
> and dynamic types of the pointer can be guaranteed to be equal at comp=
ile<br>
> time.<br>
><br>
> It seems necessary and meets my (rather simple) requirements.<br>
<br>
</span>Huh? You seem to be saying that a cloned_ptr<B> can't cons=
truct from a D*.<br>
Or that a cloned_ptr<void> can't construct from anything. The dee=
p copy can be<br>
made perfectly correct in those cases just like the "deep destruction&=
quot; can be<br>
made safe in shared_ptr; via a constructor template, construct a cloner tha=
t<br>
clones and destroys a D*, not a B*, erase its type and store it.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br></div></div></blockquote><div><=
br></div><div>The potential issue here is that the D* points to a further d=
erived DD*. If I copy it as a D I will slice it and do the wrong thing.</di=
v><div>I need to know the dynamic type of a pointer to copy the pointee cor=
rectly.</div><div><br></div><div>(apologies for earlier top post. GMail mak=
es it very easy to do.)</div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div class=3D"HOEnZb"><div class=3D"h5">
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a1143ebec2bf6fa0528dbcdf4--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 02:31:12 +0200
Raw View
On 9 January 2016 at 02:24, Jonathan Coe <jbcoe@me.com> wrote:
> I agree that it can be made safe but it cannot be guaranteed to be safe.
>
> I'm looking for stricter requirements than shared_ptr's destructor as I
> cannot make the problem go away by introducing virtual copy constructors.
> Any 'issues' with shared_ptr can be fixed with the introduction of virtual
> destructors.
Assuming that you can introduce a virtual destructor. That's not the case for
void, nor is it the case for hierarchies where the base class has a non-virtual
protected destructor, for instance. And yes, you can make the problem go away
by introducing a "virtual copy constructor", it just cannot be an
actual constructor,
and you need to pass a custom cloner. :)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 02:35:05 +0200
Raw View
On 9 January 2016 at 02:29, Jonathan Coe <jbcoe@me.com> wrote:
>> Huh? You seem to be saying that a cloned_ptr<B> can't construct from a D*.
>> Or that a cloned_ptr<void> can't construct from anything. The deep copy
>> can be
>> made perfectly correct in those cases just like the "deep destruction" can
>> be
>> made safe in shared_ptr; via a constructor template, construct a cloner
>> that
>> clones and destroys a D*, not a B*, erase its type and store it.
> The potential issue here is that the D* points to a further derived DD*. If
> I copy it as a D I will slice it and do the wrong thing.
> I need to know the dynamic type of a pointer to copy the pointee correctly.
I'm aware of that issue, but the capability of using a cloned_ptr<B>
with any derived type in the hierarchy is much more compelling to me
than absolute
safety. Granted, it's possible to first construct a cloned_ptr<DD> and
then construct
a cloned_ptr<B> from that, but I think the
converting-pointer-constructor requiring
the dynamic type to be B* seems overkill to me.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan <jonathanbcoe@gmail.com>
Date: Sat, 9 Jan 2016 00:41:51 +0000
Raw View
> On 9 Jan 2016, at 00:35, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
>
> On 9 January 2016 at 02:29, Jonathan Coe <jbcoe@me.com> wrote:
>>> Huh? You seem to be saying that a cloned_ptr<B> can't construct from a D*.
>>> Or that a cloned_ptr<void> can't construct from anything. The deep copy
>>> can be
>>> made perfectly correct in those cases just like the "deep destruction" can
>>> be
>>> made safe in shared_ptr; via a constructor template, construct a cloner
>>> that
>>> clones and destroys a D*, not a B*, erase its type and store it.
>> The potential issue here is that the D* points to a further derived DD*. If
>> I copy it as a D I will slice it and do the wrong thing.
>> I need to know the dynamic type of a pointer to copy the pointee correctly.
>
>
> I'm aware of that issue, but the capability of using a cloned_ptr<B>
> with any derived type in the hierarchy is much more compelling to me
> than absolute
> safety. Granted, it's possible to first construct a cloned_ptr<DD> and
> then construct
> a cloned_ptr<B> from that, but I think the
> converting-pointer-constructor requiring
> the dynamic type to be B* seems overkill to me.
>
Safety vs utility is a tough call. I'll work on a detailed proposal and weigh up the pros and cons of different approaches.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Patrice Roy <patricer@gmail.com>
Date: Fri, 8 Jan 2016 21:57:09 -0500
Raw View
--047d7bea43fc24fcde0528dddc17
Content-Type: text/plain; charset=UTF-8
Whenever I've done similar things, I went with:
#include <type_traits>
struct Cloneable
{
virtual Cloneable* clone() const = 0;
virtual ~Cloneable() = default;
protected:
Cloneable(const Cloneable&) = default;
};
struct Copyer
{
template <class T> T* operator()(const T &obj) const { return new
T{obj}; }
};
struct Cloner
{
template <class T> T* operator()(const T &obj) const { return
obj.clone(); }
};
template <class T>
struct dup_type
{
using type = std:conditional_t<
std::is_convertible<T*, Cloneable*>::value, Cloner, Copyer
>;
};
template <class T, class Dup = typename dup_type<T>::type>
class dup_ptr
{
T *ptr;
Dup dup;
// ...
public:
dup_ptr(const dup_ptr &other)
: ptr{ other.ptr? dup(*other.ptr) : nullptr }
{
}
// ...
};
The things that have always annoyed me were (a) using raw pointers, since
smart pointer return types in this case would not be covariant in the
clone() method, and (b) the reliance on a specific interface, although
there might be a traits-based solution to this (there's a trade-off here,
so I'm not convinced it would work for all relevant use-cases).
Apart from this, though, it works fine, and it's been useful in real-life
use-cases, so it might be useful to refine all this and make it into
something standard.
Cheers!
2016-01-08 19:41 GMT-05:00 Jonathan <jonathanbcoe@gmail.com>:
>
>
> > On 9 Jan 2016, at 00:35, Ville Voutilainen <ville.voutilainen@gmail.com>
> wrote:
> >
> > On 9 January 2016 at 02:29, Jonathan Coe <jbcoe@me.com> wrote:
> >>> Huh? You seem to be saying that a cloned_ptr<B> can't construct from a
> D*.
> >>> Or that a cloned_ptr<void> can't construct from anything. The deep copy
> >>> can be
> >>> made perfectly correct in those cases just like the "deep destruction"
> can
> >>> be
> >>> made safe in shared_ptr; via a constructor template, construct a cloner
> >>> that
> >>> clones and destroys a D*, not a B*, erase its type and store it.
> >> The potential issue here is that the D* points to a further derived
> DD*. If
> >> I copy it as a D I will slice it and do the wrong thing.
> >> I need to know the dynamic type of a pointer to copy the pointee
> correctly.
> >
> >
> > I'm aware of that issue, but the capability of using a cloned_ptr<B>
> > with any derived type in the hierarchy is much more compelling to me
> > than absolute
> > safety. Granted, it's possible to first construct a cloned_ptr<DD> and
> > then construct
> > a cloned_ptr<B> from that, but I think the
> > converting-pointer-constructor requiring
> > the dynamic type to be B* seems overkill to me.
> >
>
> Safety vs utility is a tough call. I'll work on a detailed proposal and
> weigh up the pros and cons of different approaches.
>
> > --
> >
> > ---
> > You received this message because you are subscribed to the Google
> Groups "ISO C++ Standard - Future Proposals" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to std-proposals+unsubscribe@isocpp.org.
> > To post to this group, send email to std-proposals@isocpp.org.
> > Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7bea43fc24fcde0528dddc17
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div>Whenever I've done similar things, I went wi=
th:<br><br></div><div>#include <type_traits><br></div><div>struct Clo=
neable<br>{<br>=C2=A0=C2=A0 virtual Cloneable* clone() const =3D 0;<br>=C2=
=A0=C2=A0 virtual ~Cloneable() =3D default;<br>protected:<br>=C2=A0=C2=A0 C=
loneable(const Cloneable&) =3D default;<br>};<br><br>struct Copyer<br>{=
<br>=C2=A0=C2=A0 template <class T> T* operator()(const T &obj) c=
onst { return new T{obj}; }<br>};<br><br>struct Cloner<br>{<br>=C2=A0=C2=A0=
template <class T> T* operator()(const T &obj) const { return ob=
j.clone(); }<br>};<br><br>template <class T><br>=C2=A0=C2=A0 struct d=
up_type<br>=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 using type =3D =
std:conditional_t<<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 s=
td::is_convertible<T*, Cloneable*>::value, Cloner, Copyer<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 >;<br>=C2=A0=C2=A0 };<br><br>template <class=
T, class Dup =3D typename dup_type<T>::type><br>=C2=A0=C2=A0 clas=
s dup_ptr<br>=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 T *ptr;<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Dup dup;<br>=C2=A0=C2=A0 // ...<br>=C2=A0=C2=
=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 dup_ptr(const dup_ptr &ot=
her)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : ptr{ other.ptr? =
dup(*other.ptr) : nullptr }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0 // ...<br>=C2=A0=C2=A0 };<br><br=
>The things that have always annoyed me were (a) using raw pointers, since =
smart pointer return types in this case would not be covariant in the clone=
() method, and (b) the reliance on a specific interface, although there mig=
ht be a traits-based solution to this (there's a trade-off here, so I&#=
39;m not convinced it would work for all relevant use-cases).<br><br></div>=
Apart from this, though, it works fine, and it's been useful in real-li=
fe use-cases, so it might be useful to refine all this and make it into som=
ething standard.<br><br></div>Cheers!<br><div><div><br><br></div></div></di=
v><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">2016-01-08 19:4=
1 GMT-05:00 Jonathan <span dir=3D"ltr"><<a href=3D"mailto:jonathanbcoe@g=
mail.com" target=3D"_blank">jonathanbcoe@gmail.com</a>></span>:<br><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><span class=3D""><br>
<br>
> On 9 Jan 2016, at 00:35, Ville Voutilainen <<a href=3D"mailto:ville=
..voutilainen@gmail.com">ville.voutilainen@gmail.com</a>> wrote:<br>
><br>
> On 9 January 2016 at 02:29, Jonathan Coe <<a href=3D"mailto:jbcoe@m=
e.com">jbcoe@me.com</a>> wrote:<br>
>>> Huh? You seem to be saying that a cloned_ptr<B> can'=
t construct from a D*.<br>
>>> Or that a cloned_ptr<void> can't construct from anyt=
hing. The deep copy<br>
>>> can be<br>
>>> made perfectly correct in those cases just like the "deep=
destruction" can<br>
>>> be<br>
>>> made safe in shared_ptr; via a constructor template, construct=
a cloner<br>
>>> that<br>
>>> clones and destroys a D*, not a B*, erase its type and store i=
t.<br>
>> The potential issue here is that the D* points to a further derive=
d DD*. If<br>
>> I copy it as a D I will slice it and do the wrong thing.<br>
>> I need to know the dynamic type of a pointer to copy the pointee c=
orrectly.<br>
><br>
><br>
> I'm aware of that issue, but the capability of using a cloned_ptr&=
lt;B><br>
> with any derived type in the hierarchy is much more compelling to me<b=
r>
> than absolute<br>
> safety. Granted, it's possible to first construct a cloned_ptr<=
DD> and<br>
> then construct<br>
> a cloned_ptr<B> from that, but I think the<br>
> converting-pointer-constructor requiring<br>
> the dynamic type to be B* seems overkill to me.<br>
><br>
<br>
</span>Safety vs utility is a tough call. I'll work on a detailed propo=
sal and weigh up the pros and cons of different approaches.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
> --<br>
><br>
> ---<br>
> You received this message because you are subscribed to the Google Gro=
ups "ISO C++ Standard - Future Proposals" group.<br>
> To unsubscribe from this group and stop receiving emails from it, send=
an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-=
proposals+unsubscribe@isocpp.org</a>.<br>
> To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
> Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/=
group/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.g=
oogle.com/a/isocpp.org/group/std-proposals/</a>.<br>
<br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7bea43fc24fcde0528dddc17--
.
Author: =?UTF-8?Q?Germ=C3=A1n_Diago?= <germandiago@gmail.com>
Date: Fri, 8 Jan 2016 19:33:02 -0800 (PST)
Raw View
------=_Part_751_507814118.1452310382924
Content-Type: multipart/alternative;
boundary="----=_Part_752_2049331735.1452310382924"
------=_Part_752_2049331735.1452310382924
Content-Type: text/plain; charset=UTF-8
This may be of interest for the
proposal: http://mnmlstc.github.io/core/memory.html
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_752_2049331735.1452310382924
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">This may be of interest for the proposal:=C2=A0http://mnml=
stc.github.io/core/memory.html<div><br><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_752_2049331735.1452310382924--
------=_Part_751_507814118.1452310382924--
.
Author: Patrice Roy <patricer@gmail.com>
Date: Fri, 8 Jan 2016 22:52:41 -0500
Raw View
--001a113f9b44b4bf1d0528dea2bb
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Glad if it is. It works, it works well, and I use it in specialized
contexts. The problem is that the drawbacks (mentioned in my previous
message) are a pain for standard types, at least in my mind.
I'm one of those who finds things such as the interaction between using ...
and IDisposable ... in C
2016-01-08 22:33 GMT-05:00 Germ=C3=A1n Diago <germandiago@gmail.com>:
> This may be of interest for the proposal:
> http://mnmlstc.github.io/core/memory.html
>
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--001a113f9b44b4bf1d0528dea2bb
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Glad if it is. It works, it works well, and I use it =
in specialized contexts. The problem is that the drawbacks (mentioned in my=
previous message) are a pain for standard types, at least in my mind.<br><=
br></div>I'm one of those who finds things such as the interaction betw=
een using ... and IDisposable ... in C<br></div><div class=3D"gmail_extra">=
<br><div class=3D"gmail_quote">2016-01-08 22:33 GMT-05:00 Germ=C3=A1n Diago=
<span dir=3D"ltr"><<a href=3D"mailto:germandiago@gmail.com" target=3D"_=
blank">germandiago@gmail.com</a>></span>:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr">This may be of interest for the proposal:=C2=A0<a href=
=3D"http://mnmlstc.github.io/core/memory.html" target=3D"_blank">http://mnm=
lstc.github.io/core/memory.html</a><div><br><br></div></div><div class=3D"H=
OEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a113f9b44b4bf1d0528dea2bb--
.
Author: Patrice Roy <patricer@gmail.com>
Date: Fri, 8 Jan 2016 22:53:04 -0500
Raw View
--047d7bdc15ea1dcee70528dea46b
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
.... C# unpleasant (sorry for the accidental =C2=ABsend=C2=BB)
2016-01-08 22:52 GMT-05:00 Patrice Roy <patricer@gmail.com>:
> Glad if it is. It works, it works well, and I use it in specialized
> contexts. The problem is that the drawbacks (mentioned in my previous
> message) are a pain for standard types, at least in my mind.
>
> I'm one of those who finds things such as the interaction between using
> ... and IDisposable ... in C
>
> 2016-01-08 22:33 GMT-05:00 Germ=C3=A1n Diago <germandiago@gmail.com>:
>
>> This may be of interest for the proposal:
>> http://mnmlstc.github.io/core/memory.html
>>
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to std-proposals+unsubscribe@isocpp.org.
>> To post to this group, send email to std-proposals@isocpp.org.
>> Visit this group at
>> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--047d7bdc15ea1dcee70528dea46b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">... C# unpleasant (sorry for the accidental =C2=ABsend=C2=
=BB)<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">201=
6-01-08 22:52 GMT-05:00 Patrice Roy <span dir=3D"ltr"><<a href=3D"mailto=
:patricer@gmail.com" target=3D"_blank">patricer@gmail.com</a>></span>:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Glad if it is. It wo=
rks, it works well, and I use it in specialized contexts. The problem is th=
at the drawbacks (mentioned in my previous message) are a pain for standard=
types, at least in my mind.<br><br></div>I'm one of those who finds th=
ings such as the interaction between using ... and IDisposable ... in C<br>=
</div><div class=3D"HOEnZb"><div class=3D"h5"><div class=3D"gmail_extra"><b=
r><div class=3D"gmail_quote">2016-01-08 22:33 GMT-05:00 Germ=C3=A1n Diago <=
span dir=3D"ltr"><<a href=3D"mailto:germandiago@gmail.com" target=3D"_bl=
ank">germandiago@gmail.com</a>></span>:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr">This may be of interest for the proposal:=C2=A0<a href=
=3D"http://mnmlstc.github.io/core/memory.html" target=3D"_blank">http://mnm=
lstc.github.io/core/memory.html</a><div><br><br></div></div><div><div>
<p></p>
-- <br>
<br>
--- <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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7bdc15ea1dcee70528dea46b--
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 9 Jan 2016 15:40:05 +0800
Raw View
--Apple-Mail=_5C4662CC-C85A-4D02-807A-498A86610750
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2016=E2=80=9301=E2=80=9309, at 8:41 AM, Jonathan <jonathanbcoe@gmail.c=
om> wrote:
>=20
>> On 9 Jan 2016, at 00:35, Ville Voutilainen <ville.voutilainen@gmail.com>=
wrote:
>>=20
>> I'm aware of that issue, but the capability of using a cloned_ptr<B>
>> with any derived type in the hierarchy is much more compelling to me
>> than absolute
>> safety. Granted, it's possible to first construct a cloned_ptr<DD> and
>> then construct
>> a cloned_ptr<B> from that, but I think the
>> converting-pointer-constructor requiring
>> the dynamic type to be B* seems overkill to me.
>=20
> Safety vs utility is a tough call. I'll work on a detailed proposal and w=
eigh up the pros and cons of different approaches.=20
There shouldn=E2=80=99t be any safety shortfall here. If you want, the cons=
tructor template could assert that the dynamic and static types of its argu=
ment are equal using typeid. However, C++ typically allows (dangerous) slic=
ing, so it would be an unusual restriction. For non-polymorphic types, type=
id wouldn=E2=80=99t work, but in such cases, is the most-derived object act=
ually part of the value or not? Not that the danger level is zero, but it=
=E2=80=99s probably better to follow precedents.
Best practice with an ownership facility like value_ptr is simply to apply =
it early, before any slicing happens.
I explored the interaction between custom allocation and cloning handles in=
P0043R0 <http://wg21.link/P0043R0>. For a program using memory pools, gett=
ing the custom allocator to make a clone is only half the battle. It=E2=80=
=99s also important to maintain pool invariants by transferring objects bet=
ween pools. But, as Ville mentioned, propagation traits don=E2=80=99t mix w=
ith type erasure. Library Fundamentals polymorphic memory resources (PMR) h=
elp by setting a fixed propagation policy, but that policy is container-lik=
e and not =E2=80=9Cptr=E2=80=9D-like. A PMR value_ptr would solve a slightl=
y different problem than one with a built-in, value-semantic cloner. Both p=
roblems are useful to solve.
You might consider the P0043 approach of splitting functionality between se=
parate value_ptr and value_container templates. Let value_ptr implement all=
ocator type erasure and cloning but not propagation traits nor pool transfe=
rs. It satisfies the 95% of folks who don=E2=80=99t want to think about all=
ocation. Let value_container guarantee that its value is kept in a particul=
ar pool, defined by a classic allocator. This cleanly handles the remaining=
cases, including PMR. The two templates would be interoperable, so you cou=
ld take a pooled resource, pass it to a pool-unaware library, get a clone b=
ack, and move the clone to a new pool.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--Apple-Mail=_5C4662CC-C85A-4D02-807A-498A86610750
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2016=E2=80=9301=
=E2=80=9309, at 8:41 AM, Jonathan <<a href=3D"mailto:jonathanbcoe@gmail.=
com" class=3D"">jonathanbcoe@gmail.com</a>> wrote:</div><div class=3D"">=
<br style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; f=
ont-variant: normal; font-weight: normal; letter-spacing: normal; orphans: =
auto; text-align: start; text-indent: 0px; text-transform: none; white-spac=
e: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;=
" class=3D""><blockquote type=3D"cite" style=3D"font-family: Helvetica; fon=
t-size: 12px; font-style: normal; font-variant: normal; font-weight: normal=
; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0p=
x; text-transform: none; white-space: normal; widows: auto; word-spacing: 0=
px; -webkit-text-stroke-width: 0px;" class=3D"">On 9 Jan 2016, at 00:35, Vi=
lle Voutilainen <<a href=3D"mailto:ville.voutilainen@gmail.com" class=3D=
"">ville.voutilainen@gmail.com</a>> wrote:<br class=3D""><br class=3D"">=
I'm aware of that issue, but the capability of using a cloned_ptr<B><=
br class=3D"">with any derived type in the hierarchy is much more compellin=
g to me<br class=3D"">than absolute<br class=3D"">safety. Granted, it's pos=
sible to first construct a cloned_ptr<DD> and<br class=3D"">then cons=
truct<br class=3D"">a cloned_ptr<B> from that, but I think the<br cla=
ss=3D"">converting-pointer-constructor requiring<br class=3D"">the dynamic =
type to be B* seems overkill to me.<br class=3D""></blockquote><br style=3D=
"font-family: Helvetica; font-size: 12px; font-style: normal; font-variant:=
normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-a=
lign: start; text-indent: 0px; text-transform: none; white-space: normal; w=
idows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""=
><span style=3D"font-family: Helvetica; font-size: 12px; font-style: normal=
; font-variant: normal; font-weight: normal; letter-spacing: normal; orphan=
s: auto; text-align: start; text-indent: 0px; text-transform: none; white-s=
pace: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0=
px; float: none; display: inline !important;" class=3D"">Safety vs utility =
is a tough call. I'll work on a detailed proposal and weigh up the pros and=
cons of different approaches.<span class=3D"Apple-converted-space"> <=
/span></span><br style=3D"font-family: Helvetica; font-size: 12px; font-sty=
le: normal; font-variant: normal; font-weight: normal; letter-spacing: norm=
al; orphans: auto; text-align: start; text-indent: 0px; text-transform: non=
e; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-strok=
e-width: 0px;" class=3D""></div></blockquote><div><br class=3D""></div><div=
>There shouldn=E2=80=99t be any safety shortfall here. If you want, the con=
structor template could assert that the dynamic and static types of its arg=
ument are equal using <font face=3D"Courier" class=3D"">typeid</font>. Howe=
ver, C++ typically allows (dangerous) slicing, so it would be an unusual re=
striction. For non-polymorphic types, <font face=3D"Courier" class=3D"">typ=
eid</font> wouldn=E2=80=99t work, but in such cases, is the most-derived ob=
ject actually part of the value or not? Not that the danger level is zero, =
but it=E2=80=99s probably better to follow precedents.</div><div><br class=
=3D""></div><div>Best practice with an ownership facility like <font face=
=3D"Courier" class=3D"">value_ptr</font> is simply to apply it early, befor=
e any slicing happens.</div><div><br class=3D""></div><div>I explored the i=
nteraction between custom allocation and cloning handles in <a href=3D=
"http://wg21.link/P0043R0" class=3D"">P0043R0</a>. For a program using memo=
ry pools, getting the custom allocator to make a clone is only half the bat=
tle. It=E2=80=99s also important to maintain pool invariants by transferrin=
g objects between pools. But, as Ville mentioned, propagation traits don=E2=
=80=99t mix with type erasure. Library Fundamentals polymorphic memory reso=
urces (PMR) help by setting a fixed propagation policy, but that policy is =
container-like and not =E2=80=9Cptr=E2=80=9D-like. A PMR <font face=3D"Cour=
ier" class=3D"">value_ptr</font> would solve a slightly different problem t=
han one with a built-in, value-semantic cloner. Both problems are useful to=
solve.</div><div><br class=3D""></div><div>You might consider the P0043 ap=
proach of splitting functionality between separate <font face=3D"Couri=
er" class=3D"">value_ptr</font> and <font face=3D"Courier" class=3D"">value=
_container</font> templates. Let <span style=3D"font-family: Cour=
ier;" class=3D"">value_ptr</span> implement allocator type erasure and=
cloning but not propagation traits nor pool transfers. It satisfies the 95=
% of folks who don=E2=80=99t want to think about allocation. Let <span=
style=3D"font-family: Courier;" class=3D"">value_container</span> gua=
rantee that its value is kept in a particular pool, defined by a classic al=
locator. This cleanly handles the remaining cases, including PMR. The two t=
emplates would be interoperable, so you could take a pooled resource, pass =
it to a pool-unaware library, get a clone back, and move the clone to a new=
pool.</div><div><br class=3D""></div></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail=_5C4662CC-C85A-4D02-807A-498A86610750--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 9 Jan 2016 10:19:46 -0800 (PST)
Raw View
------=_Part_2014_628025005.1452363586964
Content-Type: multipart/alternative;
boundary="----=_Part_2015_572250180.1452363586972"
------=_Part_2015_572250180.1452363586972
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Here is your code:
struct B {}; // note, no virtual destructor=20
struct D : B {~D();};=20
int main()=20
{=20
shared_ptr<B> b{new D()}; // this works fine=20
...
}
The "magic" I refer to here is that a destroyer for D rather than B is=20
apparently embedded in the newly created control block of the shared_ptr<B>=
=20
being created. Of course this is not real magic (there is no such thing)=20
but it makes a shared_ptr "better" at doing a correct destruction than a B*=
=20
would be which seems to be somewhat out of the scope of what you would=20
expect a shared pointer to do, i.e. managing a reference count.
Den l=C3=B6rdag 9 januari 2016 kl. 00:56:16 UTC+1 skrev Ville Voutilainen:
>
> On 9 January 2016 at 01:37, Bengt Gustafsson=20
> <bengt.gu...@beamways.com <javascript:>> wrote:=20
> > By the way, not even your first construction works, Ville, unless there=
=20
> is=20
> > some magic I didn't know of in shared_ptr. Doesn't it just do "delete=
=20
> _ptr"=20
>
> There's no "magic". It invokes the operator() of a default_delete<D>,=20
> which does the right=20
> thing. The incoming deleter (which is defaulted) is type-erased and=20
> invoked indirectly.=20
> The "first construction" I wrote absolutely works, and that's how it's=20
> specified.=20
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_2015_572250180.1452363586972
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Here is your code:<div><br></div><div>struct B {}; =C2=A0/=
/ note, no virtual destructor=C2=A0<br>struct D : B {~D();};=C2=A0<br><br>i=
nt main()=C2=A0<br>{=C2=A0<br>=C2=A0 =C2=A0 shared_ptr<B> b{new D()};=
// this works fine=C2=A0</div><div>=C2=A0 =C2=A0 ...</div><div>}</div><div=
><br></div><div>The "magic" I refer to here is that a destroyer f=
or D rather than B is apparently embedded in the newly created control bloc=
k of the shared_ptr<B> being created. Of course this is not real magi=
c (there is no such thing) but it makes a shared_ptr "better" at =
doing a correct destruction than a B* would be which seems to be somewhat o=
ut of the scope of what you would expect a shared pointer to do, i.e. manag=
ing a reference count.</div><div><br>Den l=C3=B6rdag 9 januari 2016 kl. 00:=
56:16 UTC+1 skrev Ville Voutilainen:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">On 9 January 2016 at 01:37, Bengt Gustafsson
<br><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
cy5L_MtqFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">bengt.gu...@beamways.com</a><wbr>> wrote:
<br>> By the way, not even your first construction works, Ville, unless =
there is
<br>> some magic I didn't know of in shared_ptr. Doesn't it just=
do "delete _ptr"
<br>
<br>There's no "magic". It invokes the operator() of a defaul=
t_delete<D>,
<br>which does the right
<br>thing. The incoming deleter (which is defaulted) is type-erased and
<br>invoked indirectly.
<br>The "first construction" I wrote absolutely works, and that&#=
39;s how it's
<br>specified.
<br></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_2015_572250180.1452363586972--
------=_Part_2014_628025005.1452363586964--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 9 Jan 2016 20:33:56 +0200
Raw View
On 9 January 2016 at 20:19, Bengt Gustafsson
<bengt.gustafsson@beamways.com> wrote:
> Here is your code:
>
> struct B {}; // note, no virtual destructor
> struct D : B {~D();};
>
> int main()
> {
> shared_ptr<B> b{new D()}; // this works fine
> ...
> }
>
> The "magic" I refer to here is that a destroyer for D rather than B is
> apparently embedded in the newly created control block of the shared_ptr<B>
Indeed. b could be shared_ptr<void>, and it would still work.
> being created. Of course this is not real magic (there is no such thing) but
> it makes a shared_ptr "better" at doing a correct destruction than a B*
> would be which seems to be somewhat out of the scope of what you would
> expect a shared pointer to do, i.e. managing a reference count.
Well, it just so happens that managing reference count for anything is quite
convenient, hence shared_ptr<void>, and the mechanism to make that work
also conveniently makes class hierarchies without virtual destructors work.
Since shared_ptr can do that, I see no reason why cloned_ptr shouldn't be
able to do it too.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 9 Jan 2016 10:47:34 -0800 (PST)
Raw View
------=_Part_2115_2021926045.1452365255021
Content-Type: multipart/alternative;
boundary="----=_Part_2116_492518672.1452365255034"
------=_Part_2116_492518672.1452365255034
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Regarding the problems with multiple inheritance:
the general problem with multiple inheritance is that casting between base=
=20
and subclass can involve addition of an offset to the this pointer.
A naive inplementation of clone_ptr would create an inner object (in your=
=20
parlance) which contains a T* to the original T and a copy constructor=20
calling virtual method. When the original deep_ptr<T> is assigned into=20
another deep_ptr<T2> where T2 is the second base of T the get() of the=20
cloned inner object would still return the non-offsetted T* which does not=
=20
point at the T2 part, and fails.
Your implementation is better than this, which is possible as the operator=
=3D=20
between deep_ptr<T> and deep_ptr<T2> knows of both these types and creates=
=20
not a plain clone of the incoming inner object but a deep_ptr<T2>::inner<T>=
=20
object, which knows how to do the cast.
However, on the second copy to a new deep_prt<T3> which has some other=20
offset of pointers there is a bad thing happening. In your case this is in=
=20
(for instance) when you do
reinterpret_cast<const typename deep_ptr<U>::inner *>(&u.buffer_)->copy(&
buffer_);
This copy() call causes a new deep_prt<T2>::inner_impl<T>() to be created=
=20
rather than the deep_ptr<T3>::inner_impl<T> that is required. This will=20
create an offsetting error when get() is called, or with virtual bases,=20
worse. Unfortunately I can't see a way around this problem, except doing=20
some offset arithmetic to sum up all the differences in the different copy=
=20
steps, and this still doesn't handle virtual base classes.
to try to make this more understandable, in this code the erroneous vtbl is=
=20
inserted:
void copy(void *buffer) const override {
new (buffer) inner_impl(new U(*u_));
}=20
This code is called in the inner object inside the deep_ptr<T2> but with=20
the buffer pointing to the member of the deep_prt<T3> so when the get()=20
method does its reinterpret_cast in:
const T *get() const {
return reinterpret_cast<const inner *>(&buffer_)->get();
}
It erroneously casts a deep_ptr<T2>::inner to a deep_ptr<T3>::inner, thus=
=20
misinterpreting the T2* that the inner object returns as a T3* with the=20
offset error as result.
This is what I think wlil happen, I haven't actually tested it and it is=20
really tricky code... I hope it works better! Also it seems that the=20
current shared_ptr would have the same issue which someone surely would=20
have discovered by now... still I can't figure out how to get around it.
Den l=C3=B6rdag 9 januari 2016 kl. 00:58:07 UTC+1 skrev Jonathan Coe:
>
>
>
> On 8 January 2016 at 23:31, Bengt Gustafsson <bengt.gu...@beamways.com=20
> <javascript:>> wrote:
>
>> Of course, but it is stlil a big difference in that you can easily add a=
=20
>> virtual destructor to the baseclass and then it will automatically work =
for=20
>> all subclasses. If you just adhere to this shuffling around the pointee=
=20
>> between different shared_ptr instances is ok. And it was my bad not to=
=20
>> include a virtual destructor in my example. What I wanted to show was th=
at=20
>> cloning could never work even with this in place (just as you remarked).
>>
>> As for your shared_ptr example (as an aside), wouldn't it be nice to be=
=20
>> able to flag that using a trait has_virtual_dtor<T> (needed on both type=
s=20
>> when doing a cross-type assignment between shared_ptrs). I guess this co=
uld=20
>> break some code, but more often would reveal bugs not hitherto detected.=
...
>>
>> After reading Jonathans implementation I doubt that this can even work=
=20
>> for the multiple-inheritance case. I don't mean just his code but in=20
>> general: The U* inside the inner<U> object gets properly cast after the=
=20
>> first copy operation, but after the second copying it wont, as the creat=
ion=20
>> of the third inner object gets the template parameter of the second, not=
=20
>> the first. It's late now and I may not be thinking straight, but at this=
=20
>> point I think it is impossible (for multiple inheritance) without help f=
rom=20
>> the pointee.
>>
>>
> If construction is only possible through a factory method, then the stati=
c=20
> type and dynamic type of the object must be the same.=20
>
> To clarify, your earlier example was of a pointer whose dynamic type=20
> differed from the static type used in the pointer constructor.
>
> 1 Base* b =3D new Sub;
> 2 clone_ptr<Base> p =3D b;
> 3 clone_ptr<Base> p2 =3D p; =20
>
> I do not allow assignment or construction from raw pointers, only from=20
> deep_ptrs (clone_ptrs) so line 2 will not compile.
>
> I don't see how multiple inheritance complicates this, can you elaborate?
> =20
>
>>
>> Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:
>>>
>>> On 8 January 2016 at 22:17, Bengt Gustafsson=20
>>> <bengt.gu...@beamways.com> wrote:=20
>>> > Nevin: The deep_ptr is supposed to clone the pointee which the=20
>>> shared_ptr never does. That's the problem here: How can the exact subcl=
ass=20
>>> of the pointee be known at the later time when the cloning is to take=
=20
>>> place.=20
>>> >=20
>>> > Many other languages support the eqivalent of a virtual copy ctor, an=
d=20
>>> it would be simple to add to C++. Of course it would be totally nonlogi=
cal=20
>>> to allow virtual on exactly the copy ctor but in practice it would feel=
=20
>>> right, I think.=20
>>>
>>>
>>> If you have a type hierarchy that can do polymorphic copies (via a=20
>>> virtual clone() or some such), then=20
>>> you can make it work. Other than that, the issue is exactly the same=20
>>> as with shared_ptr, even though=20
>>> shared_ptr doesn't clone. To explain how it's exactly the same issue=20
>>> with shared_ptr, consider:=20
>>>
>>> struct B {}; // note, no virtual destructor=20
>>> struct D : B {~D();};=20
>>>
>>> int main()=20
>>> {=20
>>> shared_ptr<B> b{new D()}; // this works fine=20
>>> B* b2 =3D new D();=20
>>> shared_ptr<B> b3{b2}; // this doesn't work=20
>>> }=20
>>>
>>> It's not an issue with cloning. It's an issue with type erasure. If=20
>>> you create a cloned_ptr<B>=20
>>> from a B*, all knowledge of the fact that the B* was actually really a=
=20
>>> D* has been lost already.=20
>>>
>> --=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:>.
>> Visit this group at=20
>> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_2116_492518672.1452365255034
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Regarding the problems with multiple inheritance:<div><br>=
</div><div>the general problem with multiple inheritance is that casting be=
tween base and subclass can involve addition of an offset to the this point=
er.</div><div><br></div><div>A naive inplementation of clone_ptr would crea=
te an inner object (in your parlance) which contains a T* to the original T=
and a copy constructor calling virtual method. When the original deep_ptr&=
lt;T> is assigned into another deep_ptr<T2> =C2=A0where T2 is the =
second base of T the get() of the cloned inner object would still return th=
e non-offsetted T* which does not point at the T2 part, and fails.</div><di=
v><br></div><div>Your implementation is better than this, which is possible=
as the operator=3D between deep_ptr<T> and deep_ptr<T2> knows =
of both these types and creates not a plain clone of the incoming inner obj=
ect but a deep_ptr<T2>::inner<T> object, which knows how to do =
the cast.</div><div><br></div><div>However, on the second copy to a new dee=
p_prt<T3> which has some other offset of pointers there is a bad thin=
g happening. In your case this is in (for instance) when you do</div><div><=
br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187=
, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code=
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: =
#000;" class=3D"styled-by-prettify">=C2=A0</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">reinterpret_cast</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> deep_ptr</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">U</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">inne=
r </span><span style=3D"color: #660;" class=3D"styled-by-prettify">*>(&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">u</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">buffer_</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)-></span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">copy</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">(&</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">buffer_</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></div></code></div><div><table class=3D"=
highlight tab-size js-file-line-container" data-tab-size=3D"8" style=3D"box=
-sizing: border-box; border-collapse: collapse; tab-size: 8; color: rgb(51,=
51, 51); font-family: Helvetica, arial, nimbussansl, liberationsans, frees=
ans, clean, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji=
9;, 'Segoe UI Symbol'; line-height: 18.2px;"><tbody style=3D"box-si=
zing: border-box;"><tr style=3D"box-sizing: border-box;"><td id=3D"LC60" cl=
ass=3D"blob-code blob-code-inner js-file-line" style=3D"box-sizing: border-=
box; padding-right: 10px; padding-left: 10px; position: relative; vertical-=
align: top; font-family: Consolas, 'Liberation Mono', Menlo, Courie=
r, monospace; font-size: 12px; white-space: pre; overflow: visible; word-wr=
ap: normal;"><br></td></tr></tbody></table>This copy() call causes a new de=
ep_prt<T2>::inner_impl<T>() to be created rather than the deep_=
ptr<T3>::inner_impl<T> that is required. This will create an of=
fsetting error when get() is called, or with virtual bases, worse. Unfortun=
ately I can't see a way around this problem, except doing some offset a=
rithmetic to sum up all the differences in the different copy steps, and th=
is still doesn't handle virtual base classes.</div><div><br></div><div>=
to try to make this more understandable, in this code the erroneous vtbl is=
inserted:</div><div><br></div><div><div class=3D"prettyprint" style=3D"bor=
der: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color:=
rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> copy</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">buffer</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">override</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">new</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">buffer</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> inn=
er_impl</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">new</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> U</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(*</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">u_</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">));</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> <br></span></div></code></div><table class=3D"highlight ta=
b-size js-file-line-container" data-tab-size=3D"8" style=3D"box-sizing: bor=
der-box; border-collapse: collapse; tab-size: 8; color: rgb(51, 51, 51); fo=
nt-family: Helvetica, arial, nimbussansl, liberationsans, freesans, clean, =
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Seg=
oe UI Symbol'; line-height: 18.2px;"><tbody style=3D"box-sizing: border=
-box;"><tr style=3D"box-sizing: border-box;"><td id=3D"LC38" class=3D"blob-=
code blob-code-inner js-file-line" style=3D"box-sizing: border-box; padding=
-right: 10px; padding-left: 10px; position: relative; vertical-align: top; =
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace=
; font-size: 12px; white-space: pre; overflow: visible; word-wrap: normal;"=
><br>
</td></tr></tbody></table>This code is called in the inner object inside th=
e deep_ptr<T2> but with the buffer pointing to the member of the deep=
_prt<T3> so when the get() method does its reinterpret_cast in:</div>=
<div><br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(18=
7, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">=C2=A0</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> T </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">*</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_cast</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> inner </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">*>(&</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">buffer_</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)-></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">get</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span></div></code></div><div>It erroneously casts a de=
ep_ptr<T2>::inner to a deep_ptr<T3>::inner, thus misinterpretin=
g the T2* that the inner object returns as a T3* with the offset error as r=
esult.</div><div><br></div><div>This is what I think wlil happen, I haven&#=
39;t actually tested it and it is really tricky code... I hope it works bet=
ter! Also it seems that the current shared_ptr would have the same issue wh=
ich someone surely would have discovered by now... still I can't figure=
out how to get around it.</div><div><br></div><div><br></div><div><br>Den =
l=C3=B6rdag 9 januari 2016 kl. 00:58:07 UTC+1 skrev Jonathan Coe:<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"><br><div><br><div class=
=3D"gmail_quote">On 8 January 2016 at 23:31, Bengt Gustafsson <span dir=3D"=
ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D=
"hF0i3eVqFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:=
';return true;" onclick=3D"this.href=3D'javascript:';return tru=
e;">bengt.gu...@beamways.com</a><wbr>></span> wrote:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"=
><div dir=3D"ltr">Of course, but it is stlil a big difference in that you c=
an easily add a virtual destructor to the baseclass and then it will automa=
tically work for all subclasses. If you just adhere to this shuffling aroun=
d the pointee between different shared_ptr instances is ok. And it was my b=
ad not to include a virtual destructor in my example. What I wanted to show=
was that cloning could never work even with this in place (just as you rem=
arked).<div><br></div><div>As for your shared_ptr example (as an aside), wo=
uldn't it be nice to be able to flag that using a trait has_virtual_dto=
r<T> (needed on both types when doing a cross-type assignment between=
shared_ptrs). I guess this could break some code, but more often would rev=
eal bugs not hitherto detected...<br><div><br><div>After reading Jonathans =
implementation I doubt that this can even work for the multiple-inheritance=
case. I don't mean just his code but in general: The U* inside the inn=
er<U> object gets properly cast after the first copy operation, but a=
fter the second copying it wont, as the creation of the third inner object =
gets the template parameter of the second, not the first. It's late now=
and I may not be thinking straight, but at this point I think it is imposs=
ible (for multiple inheritance) without help from the pointee.</div><div><s=
pan><br></span></div></div></div></div></blockquote><div><br></div><div>If =
construction is only possible through a factory method, then the static typ=
e and dynamic type of the object must be the same.=C2=A0</div><div><br></di=
v><div>To clarify, your earlier example was of a pointer whose dynamic type=
differed from the static type used in the pointer constructor.</div><div><=
br></div><div><span style=3D"font-family:monospace;font-size:10px;color:rgb=
(102,0,102)">1 Base</span><span style=3D"font-family:monospace;font-size:10=
px;color:rgb(102,102,0)">*</span><span style=3D"font-family:monospace;font-=
size:10px;color:rgb(0,0,0)">=C2=A0b=C2=A0</span><span style=3D"font-family:=
monospace;font-size:10px;color:rgb(102,102,0)">=3D</span><span style=3D"fon=
t-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0</span><span styl=
e=3D"font-family:monospace;font-size:10px;color:rgb(0,0,136)">new</span><sp=
an style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0</=
span><span style=3D"font-family:monospace;font-size:10px;color:rgb(102,0,10=
2)">Sub</span><span style=3D"font-family:monospace;font-size:10px;color:rgb=
(102,102,0)">;</span><span style=3D"font-family:monospace;font-size:10px;co=
lor:rgb(0,0,0)"><br>2 clone_ptr</span><span style=3D"font-family:monospace;=
font-size:10px;color:rgb(102,102,0)"><</span><span style=3D"font-family:=
monospace;font-size:10px;color:rgb(102,0,102)">Base</span><span style=3D"fo=
nt-family:monospace;font-size:10px;color:rgb(102,102,0)">></span><span s=
tyle=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0p=C2=
=A0</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(102=
,102,0)">=3D</span><span style=3D"font-family:monospace;font-size:10px;colo=
r:rgb(0,0,0)">=C2=A0b</span><span style=3D"font-family:monospace;font-size:=
10px;color:rgb(102,102,0)">;</span><span style=3D"font-family:monospace;fon=
t-size:10px;color:rgb(0,0,0)"><br>3 clone_ptr</span><span style=3D"font-fam=
ily:monospace;font-size:10px;color:rgb(102,102,0)"><</span><span style=
=3D"font-family:monospace;font-size:10px;color:rgb(102,0,102)">Base</span><=
span style=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)">&g=
t;</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,=
0)">=C2=A0p2=C2=A0</span><span style=3D"font-family:monospace;font-size:10p=
x;color:rgb(102,102,0)">=3D</span><span style=3D"font-family:monospace;font=
-size:10px;color:rgb(0,0,0)">=C2=A0p</span><span style=3D"font-family:monos=
pace;font-size:10px;color:rgb(102,102,0)">;</span><span style=3D"font-famil=
y:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0=C2=A0</span><br></div><=
div><br></div><div>I do not allow assignment or construction from raw point=
ers, only from deep_ptrs (clone_ptrs) so line 2 will not compile.</div><div=
><br></div><div>I don't see how multiple inheritance complicates this, =
can you elaborate?<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-col=
or:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"l=
tr"><div><div><div><span><br>Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 s=
krev Ville Voutilainen:</span><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,=
204);border-left-style:solid;padding-left:1ex"><span>On 8 January 2016 at 2=
2:17, Bengt Gustafsson
<br></span><div><div><<a rel=3D"nofollow">bengt.gu...@beamways.com</a>&g=
t; wrote:
<br>> Nevin: The deep_ptr is supposed to clone the pointee which the sha=
red_ptr never does. That's the problem here: How can the exact subclass=
of the pointee be known at the later time when the cloning is to take plac=
e.
<br>>
<br>> Many other languages support the eqivalent of a virtual copy ctor,=
and it would be simple to add to C++. Of course it would be totally nonlog=
ical to allow virtual on exactly the copy ctor but in practice it would fee=
l right, I think.
<br>
<br>
<br>If you have a type hierarchy that can do polymorphic copies (via a
<br>virtual clone() or some such), then
<br>you can make it work. Other than that, the issue is exactly the same
<br>as with shared_ptr, even though
<br>shared_ptr doesn't clone. To explain how it's exactly the same =
issue
<br>with shared_ptr, consider:
<br>
<br>struct B {}; =C2=A0// note, no virtual destructor
<br>struct D : B {~D();};
<br>
<br>int main()
<br>{
<br>=C2=A0 =C2=A0 shared_ptr<B> b{new D()}; // this works fine
<br>=C2=A0 =C2=A0 B* b2 =3D new D();
<br>=C2=A0 =C2=A0 shared_ptr<B> b3{b2}; // this doesn't work
<br>}
<br>
<br>It's not an issue with cloning. It's an issue with type erasure=
.. If
<br>you create a cloned_ptr<B>
<br>from a B*, all knowledge of the fact that the B* was actually really a
<br>D* has been lost already.
<br></div></div></blockquote></div></div></div></div><div><div>
<p></p>
-- <br>
<br>
--- <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"=
hF0i3eVqFAAJ" 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"hF0i3eVqFAAJ" 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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D'https://groups.google.com/a/isocpp.org/group/std-proposals/';r=
eturn true;" onclick=3D"this.href=3D'https://groups.google.com/a/isocpp=
..org/group/std-proposals/';return true;">https://groups.google.com/a/<w=
br>isocpp.org/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
</blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_2116_492518672.1452365255034--
------=_Part_2115_2021926045.1452365255021--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 9 Jan 2016 10:51:48 -0800 (PST)
Raw View
------=_Part_2036_1690064535.1452365508790
Content-Type: multipart/alternative;
boundary="----=_Part_2037_188146829.1452365508790"
------=_Part_2037_188146829.1452365508790
Content-Type: text/plain; charset=UTF-8
>
>
> Well, it just so happens that managing reference count for anything is
> quite
> convenient, hence shared_ptr<void>, and the mechanism to make that work
> also conveniently makes class hierarchies without virtual destructors
> work.
> Since shared_ptr can do that, I see no reason why cloned_ptr shouldn't be
> able to do it too.
>
I hope so but maybe it is not so easy, see the post that I just sent with a
compromising example (I think). Maybe there are some
restrictions on multiple inheritance or maybe I'm just plain wrong, but so
far I can't see how this could work in a general case even for shared_ptr.
(I'm not refering to shared_ptr<void> then which obviously does not have to
know anything about casting between bases and subclasses).
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2037_188146829.1452365508790
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<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;"><br>Well, it =
just so happens that managing reference count for anything is quite
<br>convenient, hence shared_ptr<void>, and the mechanism to make tha=
t work
<br>also conveniently makes class hierarchies without virtual destructors w=
ork.
<br>Since shared_ptr can do that, I see no reason why cloned_ptr shouldn=
9;t be
<br>able to do it too.
<br></blockquote><div><br></div><div>I hope so but maybe it is not so easy,=
see the post that I just sent with a compromising example (I think). Maybe=
there are some</div><div>restrictions on multiple inheritance or maybe I&#=
39;m just plain wrong, but so far I can't see how this could work in a =
general case even for shared_ptr. (I'm not refering to shared_ptr<vo=
id> then which obviously does not have to know anything about casting be=
tween bases and subclasses).</div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_2037_188146829.1452365508790--
------=_Part_2036_1690064535.1452365508790--
.
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Sat, 9 Jan 2016 20:06:32 +0000
Raw View
--Apple-Mail-300C83F2-75B7-4294-A020-9B175554AF93
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
> On 9 Jan 2016, at 18:47, Bengt Gustafsson <bengt.gustafsson@beamways.com>=
wrote:
>=20
> Regarding the problems with multiple inheritance:
>=20
> the general problem with multiple inheritance is that casting between bas=
e and subclass can involve addition of an offset to the this pointer.
>=20
> A naive inplementation of clone_ptr would create an inner object (in your=
parlance) which contains a T* to the original T and a copy constructor cal=
ling virtual method. When the original deep_ptr<T> is assigned into another=
deep_ptr<T2> where T2 is the second base of T the get() of the cloned inn=
er object would still return the non-offsetted T* which does not point at t=
he T2 part, and fails.
>=20
> Your implementation is better than this, which is possible as the operato=
r=3D between deep_ptr<T> and deep_ptr<T2> knows of both these types and cre=
ates not a plain clone of the incoming inner object but a deep_ptr<T2>::inn=
er<T> object, which knows how to do the cast.
>=20
> However, on the second copy to a new deep_prt<T3> which has some other of=
fset of pointers there is a bad thing happening. In your case this is in (f=
or instance) when you do
>=20
> reinterpret_cast<const typename deep_ptr<U>::inner *>(&u.buffer_)->copy(=
&buffer_);
>=20
> This copy() call causes a new deep_prt<T2>::inner_impl<T>() to be created=
rather than the deep_ptr<T3>::inner_impl<T> that is required. This will cr=
eate an offsetting error when get() is called, or with virtual bases, worse=
.. Unfortunately I can't see a way around this problem, except doing some of=
fset arithmetic to sum up all the differences in the different copy steps, =
and this still doesn't handle virtual base classes.
>=20
I don't think I see the problem.
deep_ptr<A>::inner_impl<T> is the same for any choice of A. The important t=
ype info is T which is retained. If T has multiple virtual bases then it kn=
ows how to apply offsets to return pointers correctly. The choice of A has =
no bearing on this.=20
I'll add Gustaffsons-dilemma as a test case.
> to try to make this more understandable, in this code the erroneous vtbl =
is inserted:
>=20
>=20
> void copy(void *buffer) const override {
> new (buffer) inner_impl(new U(*u_));
> }=20
>=20
>=20
> This code is called in the inner object inside the deep_ptr<T2> but with =
the buffer pointing to the member of the deep_prt<T3> so when the get() met=
hod does its reinterpret_cast in:
>=20
> const T *get() const {
> return reinterpret_cast<const inner *>(&buffer_)->get();
> }
>=20
> It erroneously casts a deep_ptr<T2>::inner to a deep_ptr<T3>::inner, thus=
misinterpreting the T2* that the inner object returns as a T3* with the of=
fset error as result.
>=20
> This is what I think wlil happen, I haven't actually tested it and it is =
really tricky code... I hope it works better! Also it seems that the curren=
t shared_ptr would have the same issue which someone surely would have disc=
overed by now... still I can't figure out how to get around it.
>=20
>=20
>=20
>> Den l=C3=B6rdag 9 januari 2016 kl. 00:58:07 UTC+1 skrev Jonathan Coe:
>>=20
>>=20
>>> On 8 January 2016 at 23:31, Bengt Gustafsson <bengt.gu...@beamways.com>=
wrote:
>>> Of course, but it is stlil a big difference in that you can easily add =
a virtual destructor to the baseclass and then it will automatically work f=
or all subclasses. If you just adhere to this shuffling around the pointee =
between different shared_ptr instances is ok. And it was my bad not to incl=
ude a virtual destructor in my example. What I wanted to show was that clon=
ing could never work even with this in place (just as you remarked).
>>>=20
>>> As for your shared_ptr example (as an aside), wouldn't it be nice to be=
able to flag that using a trait has_virtual_dtor<T> (needed on both types =
when doing a cross-type assignment between shared_ptrs). I guess this could=
break some code, but more often would reveal bugs not hitherto detected...
>>>=20
>>> After reading Jonathans implementation I doubt that this can even work =
for the multiple-inheritance case. I don't mean just his code but in genera=
l: The U* inside the inner<U> object gets properly cast after the first cop=
y operation, but after the second copying it wont, as the creation of the t=
hird inner object gets the template parameter of the second, not the first.=
It's late now and I may not be thinking straight, but at this point I thin=
k it is impossible (for multiple inheritance) without help from the pointee=
..
>>=20
>> If construction is only possible through a factory method, then the stat=
ic type and dynamic type of the object must be the same.=20
>>=20
>> To clarify, your earlier example was of a pointer whose dynamic type dif=
fered from the static type used in the pointer constructor.
>>=20
>> 1 Base* b =3D new Sub;
>> 2 clone_ptr<Base> p =3D b;
>> 3 clone_ptr<Base> p2 =3D p; =20
>>=20
>> I do not allow assignment or construction from raw pointers, only from d=
eep_ptrs (clone_ptrs) so line 2 will not compile.
>>=20
>> I don't see how multiple inheritance complicates this, can you elaborate=
?
>> =20
>>>=20
>>>> Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:
>>>> On 8 January 2016 at 22:17, Bengt Gustafsson=20
>>>> <bengt.gu...@beamways.com> wrote:=20
>>>> > Nevin: The deep_ptr is supposed to clone the pointee which the share=
d_ptr never does. That's the problem here: How can the exact subclass of th=
e pointee be known at the later time when the cloning is to take place.=20
>>>> >=20
>>>> > Many other languages support the eqivalent of a virtual copy ctor, a=
nd it would be simple to add to C++. Of course it would be totally nonlogic=
al to allow virtual on exactly the copy ctor but in practice it would feel =
right, I think.=20
>>>>=20
>>>>=20
>>>> If you have a type hierarchy that can do polymorphic copies (via a=20
>>>> virtual clone() or some such), then=20
>>>> you can make it work. Other than that, the issue is exactly the same=
=20
>>>> as with shared_ptr, even though=20
>>>> shared_ptr doesn't clone. To explain how it's exactly the same issue=
=20
>>>> with shared_ptr, consider:=20
>>>>=20
>>>> struct B {}; // note, no virtual destructor=20
>>>> struct D : B {~D();};=20
>>>>=20
>>>> int main()=20
>>>> {=20
>>>> shared_ptr<B> b{new D()}; // this works fine=20
>>>> B* b2 =3D new D();=20
>>>> shared_ptr<B> b3{b2}; // this doesn't work=20
>>>> }=20
>>>>=20
>>>> It's not an issue with cloning. It's an issue with type erasure. If=20
>>>> you create a cloned_ptr<B>=20
>>>> from a B*, all knowledge of the fact that the B* was actually really a=
=20
>>>> D* has been lost already.
>>>=20
>>> --=20
>>>=20
>>> ---=20
>>> You received this message because you are subscribed to the Google Grou=
ps "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send =
an email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> Visit this group at https://groups.google.com/a/isocpp.org/group/std-pr=
oposals/.
>=20
> --=20
>=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=
email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-prop=
osals/.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--Apple-Mail-300C83F2-75B7-4294-A020-9B175554AF93
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div></div><div><br></div><div><br>On 9=
Jan 2016, at 18:47, Bengt Gustafsson <<a href=3D"mailto:bengt.gustafsso=
n@beamways.com">bengt.gustafsson@beamways.com</a>> wrote:<br><br></div><=
blockquote type=3D"cite"><div><div dir=3D"ltr">Regarding the problems with =
multiple inheritance:<div><br></div><div>the general problem with multiple =
inheritance is that casting between base and subclass can involve addition =
of an offset to the this pointer.</div><div><br></div><div>A naive inplemen=
tation of clone_ptr would create an inner object (in your parlance) which c=
ontains a T* to the original T and a copy constructor calling virtual metho=
d. When the original deep_ptr<T> is assigned into another deep_ptr<=
;T2> where T2 is the second base of T the get() of the cloned inne=
r object would still return the non-offsetted T* which does not point at th=
e T2 part, and fails.</div><div><br></div><div>Your implementation is bette=
r than this, which is possible as the operator=3D between deep_ptr<T>=
and deep_ptr<T2> knows of both these types and creates not a plain c=
lone of the incoming inner object but a deep_ptr<T2>::inner<T> =
object, which knows how to do the cast.</div><div><br></div><div>However, o=
n the second copy to a new deep_prt<T3> which has some other offset o=
f pointers there is a bad thing happening. In your case this is in (for ins=
tance) when you do</div><div><br></div><div class=3D"prettyprint" style=3D"=
border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-col=
or: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprett=
yprint"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_c=
ast</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> deep_ptr</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">U</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">>::</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">inner </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*>(&</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">u</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">buffer_</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">)-></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
copy</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(&=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">buffer_</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></co=
de></div><div><table class=3D"highlight tab-size js-file-line-container" da=
ta-tab-size=3D"8" style=3D"box-sizing: border-box; border-collapse: collaps=
e; tab-size: 8; color: rgb(51, 51, 51); font-family: Helvetica, arial, nimb=
ussansl, liberationsans, freesans, clean, sans-serif, 'Apple Color Emoji', =
'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18.2px;"><tbody style=3D"=
box-sizing: border-box;"><tr style=3D"box-sizing: border-box;"><td id=3D"LC=
60" class=3D"blob-code blob-code-inner js-file-line" style=3D"box-sizing: b=
order-box; padding-right: 10px; padding-left: 10px; position: relative; ver=
tical-align: top; font-family: Consolas, 'Liberation Mono', Menlo, Courier,=
monospace; font-size: 12px; white-space: pre; overflow: visible; word-wrap=
: normal;"><br></td></tr></tbody></table>This copy() call causes a new deep=
_prt<T2>::inner_impl<T>() to be created rather than the deep_pt=
r<T3>::inner_impl<T> that is required. This will create an offs=
etting error when get() is called, or with virtual bases, worse. Unfortunat=
ely I can't see a way around this problem, except doing some offset arithme=
tic to sum up all the differences in the different copy steps, and this sti=
ll doesn't handle virtual base classes.</div><div><br></div></div></div></b=
lockquote><div><br></div><div>I don't think I see the problem.</div><div>de=
ep_ptr<A>::inner_impl<T> is the same for any choice of A. The i=
mportant type info is T which is retained. If T has multiple virtual bases =
then it knows how to apply offsets to return pointers correctly. The choice=
of A has no bearing on this. </div><div><br></div><div>I'll add Gusta=
ffsons-dilemma as a test case.</div><br><blockquote type=3D"cite"><div><div=
dir=3D"ltr"><div>to try to make this more understandable, in this code the=
erroneous vtbl is inserted:</div><div><br></div><div><div class=3D"prettyp=
rint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word;=
background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> copy<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">buffer</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">const</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">overr=
ide</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">new</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">buffer</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> inner_impl</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">new</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> U<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(*</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">u_</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> <br></span></div></code></div><table class=
=3D"highlight tab-size js-file-line-container" data-tab-size=3D"8" style=3D=
"box-sizing: border-box; border-collapse: collapse; tab-size: 8; color: rgb=
(51, 51, 51); font-family: Helvetica, arial, nimbussansl, liberationsans, f=
reesans, clean, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe U=
I Symbol'; line-height: 18.2px;"><tbody style=3D"box-sizing: border-box;"><=
tr style=3D"box-sizing: border-box;"><td id=3D"LC38" class=3D"blob-code blo=
b-code-inner js-file-line" style=3D"box-sizing: border-box; padding-right: =
10px; padding-left: 10px; position: relative; vertical-align: top; font-fam=
ily: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12p=
x; white-space: pre; overflow: visible; word-wrap: normal;"><br>
</td></tr></tbody></table>This code is called in the inner object inside th=
e deep_ptr<T2> but with the buffer pointing to the member of the deep=
_prt<T3> so when the get() method does its reinterpret_cast in:</div>=
<div><br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(18=
7, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> T </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">*</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_cast</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> inner </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">*>(&</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">buffer_</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)-></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">get</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span></div></code></div><div>It erroneously casts a de=
ep_ptr<T2>::inner to a deep_ptr<T3>::inner, thus misinterpretin=
g the T2* that the inner object returns as a T3* with the offset error as r=
esult.</div><div><br></div><div>This is what I think wlil happen, I haven't=
actually tested it and it is really tricky code... I hope it works better!=
Also it seems that the current shared_ptr would have the same issue which =
someone surely would have discovered by now... still I can't figure out how=
to get around it.</div><div><br></div><div><br></div><div><br>Den l=C3=B6r=
dag 9 januari 2016 kl. 00:58:07 UTC+1 skrev Jonathan Coe:<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"><br><div><br><div class=3D"gma=
il_quote">On 8 January 2016 at 23:31, Bengt Gustafsson <span dir=3D"ltr">&l=
t;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"hF0i3e=
VqFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return tr=
ue;" onclick=3D"this.href=3D'javascript:';return true;">bengt.gu...@beamway=
s.com</a><wbr>></span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">Of co=
urse, but it is stlil a big difference in that you can easily add a virtual=
destructor to the baseclass and then it will automatically work for all su=
bclasses. If you just adhere to this shuffling around the pointee between d=
ifferent shared_ptr instances is ok. And it was my bad not to include a vir=
tual destructor in my example. What I wanted to show was that cloning could=
never work even with this in place (just as you remarked).<div><br></div><=
div>As for your shared_ptr example (as an aside), wouldn't it be nice to be=
able to flag that using a trait has_virtual_dtor<T> (needed on both =
types when doing a cross-type assignment between shared_ptrs). I guess this=
could break some code, but more often would reveal bugs not hitherto detec=
ted...<br><div><br><div>After reading Jonathans implementation I doubt that=
this can even work for the multiple-inheritance case. I don't mean just hi=
s code but in general: The U* inside the inner<U> object gets properl=
y cast after the first copy operation, but after the second copying it wont=
, as the creation of the third inner object gets the template parameter of =
the second, not the first. It's late now and I may not be thinking straight=
, but at this point I think it is impossible (for multiple inheritance) wit=
hout help from the pointee.</div><div><span><br></span></div></div></div></=
div></blockquote><div><br></div><div>If construction is only possible throu=
gh a factory method, then the static type and dynamic type of the object mu=
st be the same. </div><div><br></div><div>To clarify, your earlier exa=
mple was of a pointer whose dynamic type differed from the static type used=
in the pointer constructor.</div><div><br></div><div><span style=3D"font-f=
amily:monospace;font-size:10px;color:rgb(102,0,102)">1 Base</span><span sty=
le=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)">*</span><s=
pan style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)"> b=
</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(=
102,102,0)">=3D</span><span style=3D"font-family:monospace;font-size:10px;c=
olor:rgb(0,0,0)"> </span><span style=3D"font-family:monospace;font-siz=
e:10px;color:rgb(0,0,136)">new</span><span style=3D"font-family:monospace;f=
ont-size:10px;color:rgb(0,0,0)"> </span><span style=3D"font-family:mon=
ospace;font-size:10px;color:rgb(102,0,102)">Sub</span><span style=3D"font-f=
amily:monospace;font-size:10px;color:rgb(102,102,0)">;</span><span style=3D=
"font-family:monospace;font-size:10px;color:rgb(0,0,0)"><br>2 clone_ptr</sp=
an><span style=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)=
"><</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(=
102,0,102)">Base</span><span style=3D"font-family:monospace;font-size:10px;=
color:rgb(102,102,0)">></span><span style=3D"font-family:monospace;font-=
size:10px;color:rgb(0,0,0)"> p </span><span style=3D"font-family:=
monospace;font-size:10px;color:rgb(102,102,0)">=3D</span><span style=3D"fon=
t-family:monospace;font-size:10px;color:rgb(0,0,0)"> b</span><span sty=
le=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)">;</span><s=
pan style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)"><br>3 c=
lone_ptr</span><span style=3D"font-family:monospace;font-size:10px;color:rg=
b(102,102,0)"><</span><span style=3D"font-family:monospace;font-size:10p=
x;color:rgb(102,0,102)">Base</span><span style=3D"font-family:monospace;fon=
t-size:10px;color:rgb(102,102,0)">></span><span style=3D"font-family:mon=
ospace;font-size:10px;color:rgb(0,0,0)"> p2 </span><span style=3D=
"font-family:monospace;font-size:10px;color:rgb(102,102,0)">=3D</span><span=
style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)"> p</s=
pan><span style=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0=
)">;</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(0,=
0,0)"> </span><br></div><div><br></div><div>I do not allow assig=
nment or construction from raw pointers, only from deep_ptrs (clone_ptrs) s=
o line 2 will not compile.</div><div><br></div><div>I don't see how multipl=
e inheritance complicates this, can you elaborate?<br></div><div> </di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid=
;padding-left:1ex"><div dir=3D"ltr"><div><div><div><span><br>Den fredag 8 j=
anuari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:</span><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1p=
x;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1=
ex"><span>On 8 January 2016 at 22:17, Bengt Gustafsson
<br></span><div><div><<a rel=3D"nofollow">bengt.gu...@beamways.com</a>&g=
t; wrote:
<br>> Nevin: The deep_ptr is supposed to clone the pointee which the sha=
red_ptr never does. That's the problem here: How can the exact subclass of =
the pointee be known at the later time when the cloning is to take place.
<br>>
<br>> Many other languages support the eqivalent of a virtual copy ctor,=
and it would be simple to add to C++. Of course it would be totally nonlog=
ical to allow virtual on exactly the copy ctor but in practice it would fee=
l right, I think.
<br>
<br>
<br>If you have a type hierarchy that can do polymorphic copies (via a
<br>virtual clone() or some such), then
<br>you can make it work. Other than that, the issue is exactly the same
<br>as with shared_ptr, even though
<br>shared_ptr doesn't clone. To explain how it's exactly the same issue
<br>with shared_ptr, consider:
<br>
<br>struct B {}; // note, no virtual destructor
<br>struct D : B {~D();};
<br>
<br>int main()
<br>{
<br> shared_ptr<B> b{new D()}; // this works fine
<br> B* b2 =3D new D();
<br> shared_ptr<B> b3{b2}; // this doesn't work
<br>}
<br>
<br>It's not an issue with cloning. It's an issue with type erasure. If
<br>you create a cloned_ptr<B>
<br>from a B*, all knowledge of the fact that the B* was actually really a
<br>D* has been lost already.
<br></div></div></blockquote></div></div></div></div><div><div>
<p></p>
-- <br>
<br>
--- <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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
hF0i3eVqFAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';ret=
urn 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"hF0i3eVqFAAJ" 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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D'https://groups.google.com/a/isocpp.org/group/std-proposals/';return tr=
ue;" onclick=3D"this.href=3D'https://groups.google.com/a/isocpp.org/group/s=
td-proposals/';return true;">https://groups.google.com/a/<wbr>isocpp.org/gr=
oup/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
</blockquote></div></div>
<p></p>
-- <br>
<br>
--- <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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br>
</div></blockquote></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail-300C83F2-75B7-4294-A020-9B175554AF93--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 9 Jan 2016 15:33:09 -0800 (PST)
Raw View
------=_Part_2400_729316668.1452382389930
Content-Type: multipart/alternative;
boundary="----=_Part_2401_948750761.1452382389931"
------=_Part_2401_948750761.1452382389931
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
No it's not: the offset addition that it has to do to convert from U to T=
=20
in get() may differ (using the tpl parameter names of your code). The=20
problem is not in copy() itself but in that copy instates an inner object=
=20
with the wrong T in the receiving object, and the offset to add depends on=
=20
the T and U combination: Wrong T, potentially wrong offset. (I hope I'm=20
wrong here but you haven't convinced me yet).
Why don't you settle this by testing? If you can't get it to fail I will=20
give it a shot tomorrow, to late now.
Den l=C3=B6rdag 9 januari 2016 kl. 21:06:38 UTC+1 skrev Jonathan Coe:
>
>
>
> On 9 Jan 2016, at 18:47, Bengt Gustafsson <bengt.gu...@beamways.com=20
> <javascript:>> wrote:
>
> Regarding the problems with multiple inheritance:
>
> the general problem with multiple inheritance is that casting between bas=
e=20
> and subclass can involve addition of an offset to the this pointer.
>
> A naive inplementation of clone_ptr would create an inner object (in your=
=20
> parlance) which contains a T* to the original T and a copy constructor=20
> calling virtual method. When the original deep_ptr<T> is assigned into=20
> another deep_ptr<T2> where T2 is the second base of T the get() of the=
=20
> cloned inner object would still return the non-offsetted T* which does no=
t=20
> point at the T2 part, and fails.
>
> Your implementation is better than this, which is possible as the=20
> operator=3D between deep_ptr<T> and deep_ptr<T2> knows of both these type=
s=20
> and creates not a plain clone of the incoming inner object but a=20
> deep_ptr<T2>::inner<T> object, which knows how to do the cast.
>
> However, on the second copy to a new deep_prt<T3> which has some other=20
> offset of pointers there is a bad thing happening. In your case this is i=
n=20
> (for instance) when you do
>
> reinterpret_cast<const typename deep_ptr<U>::inner *>(&u.buffer_)->copy(=
&
> buffer_);
>
> This copy() call causes a new deep_prt<T2>::inner_impl<T>() to be created=
=20
> rather than the deep_ptr<T3>::inner_impl<T> that is required. This will=
=20
> create an offsetting error when get() is called, or with virtual bases,=
=20
> worse. Unfortunately I can't see a way around this problem, except doing=
=20
> some offset arithmetic to sum up all the differences in the different cop=
y=20
> steps, and this still doesn't handle virtual base classes.
>
>
> I don't think I see the problem.
> deep_ptr<A>::inner_impl<T> is the same for any choice of A. The important=
=20
> type info is T which is retained. If T has multiple virtual bases then it=
=20
> knows how to apply offsets to return pointers correctly. The choice of A=
=20
> has no bearing on this.=20
>
> I'll add Gustaffsons-dilemma as a test case.
>
> to try to make this more understandable, in this code the erroneous vtbl=
=20
> is inserted:
>
>
> void copy(void *buffer) const override {
> new (buffer) inner_impl(new U(*u_));
> }=20
>
> This code is called in the inner object inside the deep_ptr<T2> but with=
=20
> the buffer pointing to the member of the deep_prt<T3> so when the get()=
=20
> method does its reinterpret_cast in:
>
> const T *get() const {
> return reinterpret_cast<const inner *>(&buffer_)->get();
> }
>
> It erroneously casts a deep_ptr<T2>::inner to a deep_ptr<T3>::inner, thus=
=20
> misinterpreting the T2* that the inner object returns as a T3* with the=
=20
> offset error as result.
>
> This is what I think wlil happen, I haven't actually tested it and it is=
=20
> really tricky code... I hope it works better! Also it seems that the=20
> current shared_ptr would have the same issue which someone surely would=
=20
> have discovered by now... still I can't figure out how to get around it.
>
>
>
> Den l=C3=B6rdag 9 januari 2016 kl. 00:58:07 UTC+1 skrev Jonathan Coe:
>>
>>
>>
>> On 8 January 2016 at 23:31, Bengt Gustafsson <bengt.gu...@beamways.com>=
=20
>> wrote:
>>
>>> Of course, but it is stlil a big difference in that you can easily add =
a=20
>>> virtual destructor to the baseclass and then it will automatically work=
for=20
>>> all subclasses. If you just adhere to this shuffling around the pointee=
=20
>>> between different shared_ptr instances is ok. And it was my bad not to=
=20
>>> include a virtual destructor in my example. What I wanted to show was t=
hat=20
>>> cloning could never work even with this in place (just as you remarked)=
..
>>>
>>> As for your shared_ptr example (as an aside), wouldn't it be nice to be=
=20
>>> able to flag that using a trait has_virtual_dtor<T> (needed on both typ=
es=20
>>> when doing a cross-type assignment between shared_ptrs). I guess this c=
ould=20
>>> break some code, but more often would reveal bugs not hitherto detected=
....
>>>
>>> After reading Jonathans implementation I doubt that this can even work=
=20
>>> for the multiple-inheritance case. I don't mean just his code but in=20
>>> general: The U* inside the inner<U> object gets properly cast after the=
=20
>>> first copy operation, but after the second copying it wont, as the crea=
tion=20
>>> of the third inner object gets the template parameter of the second, no=
t=20
>>> the first. It's late now and I may not be thinking straight, but at thi=
s=20
>>> point I think it is impossible (for multiple inheritance) without help =
from=20
>>> the pointee.
>>>
>>>
>> If construction is only possible through a factory method, then the=20
>> static type and dynamic type of the object must be the same.=20
>>
>> To clarify, your earlier example was of a pointer whose dynamic type=20
>> differed from the static type used in the pointer constructor.
>>
>> 1 Base* b =3D new Sub;
>> 2 clone_ptr<Base> p =3D b;
>> 3 clone_ptr<Base> p2 =3D p; =20
>>
>> I do not allow assignment or construction from raw pointers, only from=
=20
>> deep_ptrs (clone_ptrs) so line 2 will not compile.
>>
>> I don't see how multiple inheritance complicates this, can you elaborate=
?
>> =20
>>
>>>
>>> Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:
>>>>
>>>> On 8 January 2016 at 22:17, Bengt Gustafsson=20
>>>> <bengt.gu...@beamways.com> wrote:=20
>>>> > Nevin: The deep_ptr is supposed to clone the pointee which the=20
>>>> shared_ptr never does. That's the problem here: How can the exact subc=
lass=20
>>>> of the pointee be known at the later time when the cloning is to take=
=20
>>>> place.=20
>>>> >=20
>>>> > Many other languages support the eqivalent of a virtual copy ctor,=
=20
>>>> and it would be simple to add to C++. Of course it would be totally=20
>>>> nonlogical to allow virtual on exactly the copy ctor but in practice i=
t=20
>>>> would feel right, I think.=20
>>>>
>>>>
>>>> If you have a type hierarchy that can do polymorphic copies (via a=20
>>>> virtual clone() or some such), then=20
>>>> you can make it work. Other than that, the issue is exactly the same=
=20
>>>> as with shared_ptr, even though=20
>>>> shared_ptr doesn't clone. To explain how it's exactly the same issue=
=20
>>>> with shared_ptr, consider:=20
>>>>
>>>> struct B {}; // note, no virtual destructor=20
>>>> struct D : B {~D();};=20
>>>>
>>>> int main()=20
>>>> {=20
>>>> shared_ptr<B> b{new D()}; // this works fine=20
>>>> B* b2 =3D new D();=20
>>>> shared_ptr<B> b3{b2}; // this doesn't work=20
>>>> }=20
>>>>
>>>> It's not an issue with cloning. It's an issue with type erasure. If=20
>>>> you create a cloned_ptr<B>=20
>>>> from a B*, all knowledge of the fact that the B* was actually really a=
=20
>>>> D* has been lost already.=20
>>>>
>>> --=20
>>>
>>> ---=20
>>> You received this message because you are subscribed to the Google=20
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send=
=20
>>> an email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> Visit this group at=20
>>> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>
>> --=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:>.
> Visit this group at=20
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_2401_948750761.1452382389931
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">No it's not: the offset addition that it has to do to =
convert from U to T in get() may differ (using the tpl parameter names of y=
our code). The problem is not in copy() itself but in that copy instates an=
inner object with the wrong T in the receiving object, and the offset to a=
dd depends on the T and U combination: Wrong T, potentially wrong offset. (=
I hope I'm wrong here but you haven't convinced me yet).<div><br></=
div><div>Why don't you settle this by testing? If you can't get it =
to fail I will give it a shot tomorrow, to late now.</div><div><div><br>Den=
l=C3=B6rdag 9 januari 2016 kl. 21:06:38 UTC+1 skrev Jonathan Coe:<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"auto"><div></div><div><br><=
/div><div><br>On 9 Jan 2016, at 18:47, Bengt Gustafsson <<a href=3D"java=
script:" target=3D"_blank" gdf-obfuscated-mailto=3D"qk2AzNisFAAJ" rel=3D"no=
follow" onmousedown=3D"this.href=3D'javascript:';return true;" oncl=
ick=3D"this.href=3D'javascript:';return true;">bengt.gu...@beamways=
..com</a><wbr>> wrote:<br><br></div><blockquote type=3D"cite"><div><div d=
ir=3D"ltr">Regarding the problems with multiple inheritance:<div><br></div>=
<div>the general problem with multiple inheritance is that casting between =
base and subclass can involve addition of an offset to the this pointer.</d=
iv><div><br></div><div>A naive inplementation of clone_ptr would create an =
inner object (in your parlance) which contains a T* to the original T and a=
copy constructor calling virtual method. When the original deep_ptr<T&g=
t; is assigned into another deep_ptr<T2> =C2=A0where T2 is the second=
base of T the get() of the cloned inner object would still return the non-=
offsetted T* which does not point at the T2 part, and fails.</div><div><br>=
</div><div>Your implementation is better than this, which is possible as th=
e operator=3D between deep_ptr<T> and deep_ptr<T2> knows of bot=
h these types and creates not a plain clone of the incoming inner object bu=
t a deep_ptr<T2>::inner<T> object, which knows how to do the ca=
st.</div><div><br></div><div>However, on the second copy to a new deep_prt&=
lt;T3> which has some other offset of pointers there is a bad thing happ=
ening. In your case this is in (for instance) when you do</div><div><br></d=
iv><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;bac=
kground-color:rgb(250,250,250)"><code><div><span style=3D"color:#000">=C2=
=A0</span><span style=3D"color:#008">reinterpret_cast</span><span style=3D"=
color:#660"><</span><span style=3D"color:#008">const</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> deep_ptr</span><span style=3D"color:#660"><</span><sp=
an style=3D"color:#000">U</span><span style=3D"color:#660">>::</span><sp=
an style=3D"color:#000">inner </span><span style=3D"color:#660">*>(&=
</span><span style=3D"color:#000">u</span><span style=3D"color:#660">.</spa=
n><span style=3D"color:#000">buffer_</span><span style=3D"color:#660">)->=
;</span><span style=3D"color:#000">copy</span><span style=3D"color:#660">(&=
amp;</span><span style=3D"color:#000">buffer_</span><span style=3D"color:#6=
60">)<wbr>;</span><span style=3D"color:#000"><br></span></div></code></div>=
<div><table style=3D"border-collapse:collapse;color:rgb(51,51,51);font-fami=
ly:Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,=
9;Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'=
;line-height:18.2px"><tbody><tr><td style=3D"padding-right:10px;padding-lef=
t:10px;vertical-align:top;font-family:Consolas,'Liberation Mono',Me=
nlo,Courier,monospace;font-size:12px;white-space:pre;overflow:visible;word-=
wrap:normal"><br></td></tr></tbody></table>This copy() call causes a new de=
ep_prt<T2>::inner_impl<T>() to be created rather than the deep_=
ptr<T3>::inner_impl<T> that is required. This will create an of=
fsetting error when get() is called, or with virtual bases, worse. Unfortun=
ately I can't see a way around this problem, except doing some offset a=
rithmetic to sum up all the differences in the different copy steps, and th=
is still doesn't handle virtual base classes.</div><div><br></div></div=
></div></blockquote><div><br></div><div>I don't think I see the problem=
..</div><div>deep_ptr<A>::inner_impl<T> is the same for any choi=
ce of A. The important type info is T which is retained. If T has multiple =
virtual bases then it knows how to apply offsets to return pointers correct=
ly. The choice of A has no bearing on this.=C2=A0</div><div><br></div><div>=
I'll add Gustaffsons-dilemma as a test case.</div><br><blockquote type=
=3D"cite"><div><div dir=3D"ltr"><div>to try to make this more understandabl=
e, in this code the erroneous vtbl is inserted:</div><div><br></div><div><d=
iv style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;backgrou=
nd-color:rgb(250,250,250)"><code><div><span style=3D"color:#000"><br></span=
><span style=3D"color:#008">void</span><span style=3D"color:#000"> copy</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#008">void</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">*</span><spa=
n style=3D"color:#000">buffer</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">const</span><span=
style=3D"color:#000"> </span><span style=3D"color:#008">override</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"><br>=C2=A0</span><span style=3D"color:#008">new</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">buffer</span><span style=3D"color:#660">)</span><span s=
tyle=3D"color:#000"> inner_impl</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#008">new</span><span style=3D"color:#000"> U</span><spa=
n style=3D"color:#660">(*</span><span style=3D"color:#000">u_</span><span s=
tyle=3D"color:#660">));</span><span style=3D"color:#000"><br>=C2=A0</span><=
span style=3D"color:#660">}</span><span style=3D"color:#000"> <br></span></=
div></code></div><table style=3D"border-collapse:collapse;color:rgb(51,51,5=
1);font-family:Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sa=
ns-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI=
Symbol';line-height:18.2px"><tbody><tr><td style=3D"padding-right:10px=
;padding-left:10px;vertical-align:top;font-family:Consolas,'Liberation =
Mono',Menlo,Courier,monospace;font-size:12px;white-space:pre;overflow:v=
isible;word-wrap:normal"><br>
</td></tr></tbody></table>This code is called in the inner object inside th=
e deep_ptr<T2> but with the buffer pointing to the member of the deep=
_prt<T3> so when the get() method does its reinterpret_cast in:</div>=
<div><br></div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:br=
eak-word;background-color:rgb(250,250,250)"><code><div><span style=3D"color=
:#000">=C2=A0</span><span style=3D"color:#008">const</span><span style=3D"c=
olor:#000"> T </span><span style=3D"color:#660">*</span><span style=3D"colo=
r:#008">get</span><span style=3D"color:#660">()</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">const</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000">=
<br>=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#008">return</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">reinterpret_cast<=
/span><span style=3D"color:#660"><</span><span style=3D"color:#008">cons=
t</span><span style=3D"color:#000"> inner </span><span style=3D"color:#660"=
>*>(&</span><span style=3D"color:#000">buffer_</span><span style=3D"=
color:#660">)-></span><span style=3D"color:#008">get</span><span style=
=3D"color:#660">();</span><span style=3D"color:#000"><br>=C2=A0</span><span=
style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span></d=
iv></code></div><div>It erroneously casts a deep_ptr<T2>::inner to a =
deep_ptr<T3>::inner, thus misinterpreting the T2* that the inner obje=
ct returns as a T3* with the offset error as result.</div><div><br></div><d=
iv>This is what I think wlil happen, I haven't actually tested it and i=
t is really tricky code... I hope it works better! Also it seems that the c=
urrent shared_ptr would have the same issue which someone surely would have=
discovered by now... still I can't figure out how to get around it.</d=
iv><div><br></div><div><br></div><div><br>Den l=C3=B6rdag 9 januari 2016 kl=
.. 00:58:07 UTC+1 skrev Jonathan Coe:<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><div><br><div class=3D"gmail_quote">On 8 January 2016=
at 23:31, Bengt Gustafsson <span dir=3D"ltr"><<a rel=3D"nofollow">bengt=
..gu...@beamways.com</a>></span> wrote:<br><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-col=
or:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"l=
tr">Of course, but it is stlil a big difference in that you can easily add =
a virtual destructor to the baseclass and then it will automatically work f=
or all subclasses. If you just adhere to this shuffling around the pointee =
between different shared_ptr instances is ok. And it was my bad not to incl=
ude a virtual destructor in my example. What I wanted to show was that clon=
ing could never work even with this in place (just as you remarked).<div><b=
r></div><div>As for your shared_ptr example (as an aside), wouldn't it =
be nice to be able to flag that using a trait has_virtual_dtor<T> (ne=
eded on both types when doing a cross-type assignment between shared_ptrs).=
I guess this could break some code, but more often would reveal bugs not h=
itherto detected...<br><div><br><div>After reading Jonathans implementation=
I doubt that this can even work for the multiple-inheritance case. I don&#=
39;t mean just his code but in general: The U* inside the inner<U> ob=
ject gets properly cast after the first copy operation, but after the secon=
d copying it wont, as the creation of the third inner object gets the templ=
ate parameter of the second, not the first. It's late now and I may not=
be thinking straight, but at this point I think it is impossible (for mult=
iple inheritance) without help from the pointee.</div><div><span><br></span=
></div></div></div></div></blockquote><div><br></div><div>If construction i=
s only possible through a factory method, then the static type and dynamic =
type of the object must be the same.=C2=A0</div><div><br></div><div>To clar=
ify, your earlier example was of a pointer whose dynamic type differed from=
the static type used in the pointer constructor.</div><div><br></div><div>=
<span style=3D"font-family:monospace;font-size:10px;color:rgb(102,0,102)">1=
Base</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(1=
02,102,0)">*</span><span style=3D"font-family:monospace;font-size:10px;colo=
r:rgb(0,0,0)">=C2=A0b=C2=A0</span><span style=3D"font-family:monospace;font=
-size:10px;color:rgb(102,102,0)">=3D</span><span style=3D"font-family:monos=
pace;font-size:10px;color:rgb(0,0,0)">=C2=A0</span><span style=3D"font-fami=
ly:monospace;font-size:10px;color:rgb(0,0,136)">new</span><span style=3D"fo=
nt-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0</span><span sty=
le=3D"font-family:monospace;font-size:10px;color:rgb(102,0,102)">Sub</span>=
<span style=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)">;=
</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)=
"><br>2 clone_ptr</span><span style=3D"font-family:monospace;font-size:10px=
;color:rgb(102,102,0)"><</span><span style=3D"font-family:monospace;font=
-size:10px;color:rgb(102,0,102)">Base</span><span style=3D"font-family:mono=
space;font-size:10px;color:rgb(102,102,0)">></span><span style=3D"font-f=
amily:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0p=C2=A0</span><span =
style=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)">=3D</sp=
an><span style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=
=C2=A0b</span><span style=3D"font-family:monospace;font-size:10px;color:rgb=
(102,102,0)">;</span><span style=3D"font-family:monospace;font-size:10px;co=
lor:rgb(0,0,0)"><br>3 clone_ptr</span><span style=3D"font-family:monospace;=
font-size:10px;color:rgb(102,102,0)"><</span><span style=3D"font-family:=
monospace;font-size:10px;color:rgb(102,0,102)">Base</span><span style=3D"fo=
nt-family:monospace;font-size:10px;color:rgb(102,102,0)">></span><span s=
tyle=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0p2=C2=
=A0</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(102=
,102,0)">=3D</span><span style=3D"font-family:monospace;font-size:10px;colo=
r:rgb(0,0,0)">=C2=A0p</span><span style=3D"font-family:monospace;font-size:=
10px;color:rgb(102,102,0)">;</span><span style=3D"font-family:monospace;fon=
t-size:10px;color:rgb(0,0,0)">=C2=A0=C2=A0</span><br></div><div><br></div><=
div>I do not allow assignment or construction from raw pointers, only from =
deep_ptrs (clone_ptrs) so line 2 will not compile.</div><div><br></div><div=
>I don't see how multiple inheritance complicates this, can you elabora=
te?<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,=
204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div><div><=
div><span><br>Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Vout=
ilainen:</span><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>On 8 January 2016 at 22:17, Bengt Gus=
tafsson
<br></span><div><div><<a rel=3D"nofollow">bengt.gu...@beamways.com</a>&g=
t; wrote:
<br>> Nevin: The deep_ptr is supposed to clone the pointee which the sha=
red_ptr never does. That's the problem here: How can the exact subclass=
of the pointee be known at the later time when the cloning is to take plac=
e.
<br>>
<br>> Many other languages support the eqivalent of a virtual copy ctor,=
and it would be simple to add to C++. Of course it would be totally nonlog=
ical to allow virtual on exactly the copy ctor but in practice it would fee=
l right, I think.
<br>
<br>
<br>If you have a type hierarchy that can do polymorphic copies (via a
<br>virtual clone() or some such), then
<br>you can make it work. Other than that, the issue is exactly the same
<br>as with shared_ptr, even though
<br>shared_ptr doesn't clone. To explain how it's exactly the same =
issue
<br>with shared_ptr, consider:
<br>
<br>struct B {}; =C2=A0// note, no virtual destructor
<br>struct D : B {~D();};
<br>
<br>int main()
<br>{
<br>=C2=A0 =C2=A0 shared_ptr<B> b{new D()}; // this works fine
<br>=C2=A0 =C2=A0 B* b2 =3D new D();
<br>=C2=A0 =C2=A0 shared_ptr<B> b3{b2}; // this doesn't work
<br>}
<br>
<br>It's not an issue with cloning. It's an issue with type erasure=
.. If
<br>you create a cloned_ptr<B>
<br>from a B*, all knowledge of the fact that the B* was actually really a
<br>D* has been lost already.
<br></div></div></blockquote></div></div></div></div><div><div>
<p></p>
-- <br>
<br>
--- <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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.hre=
f=3D'https://groups.google.com/a/isocpp.org/group/std-proposals/';r=
eturn true;" onclick=3D"this.href=3D'https://groups.google.com/a/isocpp=
..org/group/std-proposals/';return true;">https://groups.google.com/a/<w=
br>isocpp.org/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
</blockquote></div></div>
<p></p>
-- <br>
<br>
--- <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"=
qk2AzNisFAAJ" 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"qk2AzNisFAAJ" 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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D'https://groups.google.com/a/isocpp.org/group/std-proposals/';r=
eturn true;" onclick=3D"this.href=3D'https://groups.google.com/a/isocpp=
..org/group/std-proposals/';return true;">https://groups.google.com/a/<w=
br>isocpp.org/group/std-<wbr>proposals/</a>.<br>
</div></blockquote></div></blockquote></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_2401_948750761.1452382389931--
------=_Part_2400_729316668.1452382389930--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 01:49:29 +0200
Raw View
--001a11439d02d6464d0528ef5a0e
Content-Type: text/plain; charset=UTF-8
On 10 January 2016 at 01:33, Bengt Gustafsson <bengt.gustafsson@beamways.com
> wrote:
> No it's not: the offset addition that it has to do to convert from U to T
> in get() may differ (using the tpl parameter names of your code). The
> problem is not in copy() itself but in that copy instates an inner object
> with the wrong T in the receiving object, and the offset to add depends on
> the T and U combination: Wrong T, potentially wrong offset. (I hope I'm
> wrong here but you haven't convinced me yet).
>
The offset depends on the call entry's type(*) and the covariant type the
type-erased override
actually returns. shared_ptr works fine with the case you think is
problematic, because
the offset is adjusted at run-time. I don't know whether Jonathan's
implementation gets it
right with its reinterpret_cast dance, but shared_ptr and my implementation
do.
(*) For a cloned_ptr<B1>, that type is B1*. For cloned_ptr<B2>, that type
is B2*. The run-time
offset adjustment does the right thing for both, even though the override
of the pointer-getting
function in the type-erased implementation returns a D* (assuming struct D
: B1, B2 {}).
This doesn't even have much to do with multiple inheritance, the same issue
would arise
with
struct B {};
struct D : B {};
struct E : D {};
and converting E* to D* or B*, depending on who's calling. :)
This might be illuminating:
https://mentorembedded.github.io/cxx-abi/abi.html#vtable-components
"In particular, if the derived class overrides a base class virtual
function with a different (covariant) return type, the entry for the
derived class comes after the primary base's embedded virtual table in
declaration order, and is the entry used for calls from the derived class
without adjustment. The entry in the embedded primary virtual table points
to a routine that adjusts the result pointer before returning."
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11439d02d6464d0528ef5a0e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On 10 January 2016 at 01:33, Bengt Gustafsson <span dir=3D"ltr"><<a =
href=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gusta=
fsson@beamways.com</a>></span> wrote:<br><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr">No it's not: the offset addition th=
at it has to do to convert from U to T in get() may differ (using the tpl p=
arameter names of your code). The problem is not in copy() itself but in th=
at copy instates an inner object with the wrong T in the receiving object, =
and the offset to add depends on the T and U combination: Wrong T, potentia=
lly wrong offset. (I hope I'm wrong here but you haven't convinced =
me yet).</div></blockquote><div><br></div><div>The offset depends on the ca=
ll entry's type(*) and the covariant type the type-erased override<br><=
/div><div>actually returns. shared_ptr works fine with the case you think i=
s problematic, because<br></div><div>the offset is adjusted at run-time. I =
don't know whether Jonathan's implementation gets it<br></div><div>=
right with its reinterpret_cast dance, but shared_ptr and my implementation=
do.<br><br></div><div>(*) For a cloned_ptr<B1>, that type is B1*. Fo=
r cloned_ptr<B2>, that type is B2*. The run-time<br></div><div>offset=
adjustment does the right thing for both, even though the override of the =
pointer-getting<br></div><div>function in the type-erased implementation re=
turns a D* (assuming struct D : B1, B2 {}).<br><br></div><div>This doesn=
9;t even have much to do with multiple inheritance, the same issue would ar=
ise<br></div><div>with<br><br></div><div>struct B {};<br><br></div><div>str=
uct D : B {};<br><br></div><div>struct E : D {};<br><br></div><div>and conv=
erting E* to D* or B*, depending on who's calling. :)<br><br></div><div=
>This might be illuminating:<br><a href=3D"https://mentorembedded.github.io=
/cxx-abi/abi.html#vtable-components">https://mentorembedded.github.io/cxx-a=
bi/abi.html#vtable-components</a><br><br>"<a name=3D"q1">In particular=
, if the derived class overrides a base class virtual
function with a different (covariant) return type,
the entry for the derived class comes after the primary base's
embedded virtual table in declaration order,
and is the entry used for calls from the derived class without adjustment.
The entry in the embedded primary virtual table points to a routine
that adjusts the result pointer before returning."</a></div></div></di=
v></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a11439d02d6464d0528ef5a0e--
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sun, 10 Jan 2016 00:11:00 +0000
Raw View
--001a11454ffacba3d30528efa78e
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On 9 January 2016 at 23:33, Bengt Gustafsson <bengt.gustafsson@beamways.com=
>
wrote:
> No it's not: the offset addition that it has to do to convert from U to T
> in get() may differ (using the tpl parameter names of your code). The
> problem is not in copy() itself but in that copy instates an inner object
> with the wrong T in the receiving object, and the offset to add depends o=
n
> the T and U combination: Wrong T, potentially wrong offset. (I hope I'm
> wrong here but you haven't convinced me yet).
>
> Why don't you settle this by testing? If you can't get it to fail I will
> give it a shot tomorrow, to late now.
>
>
I have settled this by testing. You are correct.
I've restricted my design, following Germ=C3=A1n Diago's example, somewhat =
so
that copies and assignment from different types cannot take place. This
resolves "Gustafsson's dilemma" albeit somewhat unsatisfactorarily. The
restricted design is still fit for my original purpose. I'll add notes on
this to the draft proposal. Thanks for your continued interest and
contribution.
> Den l=C3=B6rdag 9 januari 2016 kl. 21:06:38 UTC+1 skrev Jonathan Coe:
>
>>
>>
>> On 9 Jan 2016, at 18:47, Bengt Gustafsson <bengt.gu...@beamways.com>
>> wrote:
>>
>> Regarding the problems with multiple inheritance:
>>
>> the general problem with multiple inheritance is that casting between
>> base and subclass can involve addition of an offset to the this pointer.
>>
>> A naive inplementation of clone_ptr would create an inner object (in you=
r
>> parlance) which contains a T* to the original T and a copy constructor
>> calling virtual method. When the original deep_ptr<T> is assigned into
>> another deep_ptr<T2> where T2 is the second base of T the get() of the
>> cloned inner object would still return the non-offsetted T* which does n=
ot
>> point at the T2 part, and fails.
>>
>> Your implementation is better than this, which is possible as the
>> operator=3D between deep_ptr<T> and deep_ptr<T2> knows of both these typ=
es
>> and creates not a plain clone of the incoming inner object but a
>> deep_ptr<T2>::inner<T> object, which knows how to do the cast.
>>
>> However, on the second copy to a new deep_prt<T3> which has some other
>> offset of pointers there is a bad thing happening. In your case this is =
in
>> (for instance) when you do
>>
>> reinterpret_cast<const typename deep_ptr<U>::inner *>(&u.buffer_)->copy
>> (&buffer_);
>>
>> This copy() call causes a new deep_prt<T2>::inner_impl<T>() to be create=
d
>> rather than the deep_ptr<T3>::inner_impl<T> that is required. This will
>> create an offsetting error when get() is called, or with virtual bases,
>> worse. Unfortunately I can't see a way around this problem, except doing
>> some offset arithmetic to sum up all the differences in the different co=
py
>> steps, and this still doesn't handle virtual base classes.
>>
>>
>> I don't think I see the problem.
>> deep_ptr<A>::inner_impl<T> is the same for any choice of A. The importan=
t
>> type info is T which is retained. If T has multiple virtual bases then i=
t
>> knows how to apply offsets to return pointers correctly. The choice of A
>> has no bearing on this.
>>
>> I'll add Gustaffsons-dilemma as a test case.
>>
>> to try to make this more understandable, in this code the erroneous vtbl
>> is inserted:
>>
>>
>> void copy(void *buffer) const override {
>> new (buffer) inner_impl(new U(*u_));
>> }
>>
>> This code is called in the inner object inside the deep_ptr<T2> but with
>> the buffer pointing to the member of the deep_prt<T3> so when the get()
>> method does its reinterpret_cast in:
>>
>> const T *get() const {
>> return reinterpret_cast<const inner *>(&buffer_)->get();
>> }
>>
>> It erroneously casts a deep_ptr<T2>::inner to a deep_ptr<T3>::inner, thu=
s
>> misinterpreting the T2* that the inner object returns as a T3* with the
>> offset error as result.
>>
>> This is what I think wlil happen, I haven't actually tested it and it is
>> really tricky code... I hope it works better! Also it seems that the
>> current shared_ptr would have the same issue which someone surely would
>> have discovered by now... still I can't figure out how to get around it.
>>
>>
>>
>> Den l=C3=B6rdag 9 januari 2016 kl. 00:58:07 UTC+1 skrev Jonathan Coe:
>>>
>>>
>>>
>>> On 8 January 2016 at 23:31, Bengt Gustafsson <bengt.gu...@beamways.com>
>>> wrote:
>>>
>>>> Of course, but it is stlil a big difference in that you can easily add
>>>> a virtual destructor to the baseclass and then it will automatically w=
ork
>>>> for all subclasses. If you just adhere to this shuffling around the po=
intee
>>>> between different shared_ptr instances is ok. And it was my bad not to
>>>> include a virtual destructor in my example. What I wanted to show was =
that
>>>> cloning could never work even with this in place (just as you remarked=
).
>>>>
>>>> As for your shared_ptr example (as an aside), wouldn't it be nice to b=
e
>>>> able to flag that using a trait has_virtual_dtor<T> (needed on both ty=
pes
>>>> when doing a cross-type assignment between shared_ptrs). I guess this =
could
>>>> break some code, but more often would reveal bugs not hitherto detecte=
d...
>>>>
>>>> After reading Jonathans implementation I doubt that this can even work
>>>> for the multiple-inheritance case. I don't mean just his code but in
>>>> general: The U* inside the inner<U> object gets properly cast after th=
e
>>>> first copy operation, but after the second copying it wont, as the cre=
ation
>>>> of the third inner object gets the template parameter of the second, n=
ot
>>>> the first. It's late now and I may not be thinking straight, but at th=
is
>>>> point I think it is impossible (for multiple inheritance) without help=
from
>>>> the pointee.
>>>>
>>>>
>>> If construction is only possible through a factory method, then the
>>> static type and dynamic type of the object must be the same.
>>>
>>> To clarify, your earlier example was of a pointer whose dynamic type
>>> differed from the static type used in the pointer constructor.
>>>
>>> 1 Base* b =3D new Sub;
>>> 2 clone_ptr<Base> p =3D b;
>>> 3 clone_ptr<Base> p2 =3D p;
>>>
>>> I do not allow assignment or construction from raw pointers, only from
>>> deep_ptrs (clone_ptrs) so line 2 will not compile.
>>>
>>> I don't see how multiple inheritance complicates this, can you elaborat=
e?
>>>
>>>
>>>>
>>>> Den fredag 8 januari 2016 kl. 21:25:57 UTC+1 skrev Ville Voutilainen:
>>>>>
>>>>> On 8 January 2016 at 22:17, Bengt Gustafsson
>>>>> <bengt.gu...@beamways.com> wrote:
>>>>> > Nevin: The deep_ptr is supposed to clone the pointee which the
>>>>> shared_ptr never does. That's the problem here: How can the exact sub=
class
>>>>> of the pointee be known at the later time when the cloning is to take
>>>>> place.
>>>>> >
>>>>> > Many other languages support the eqivalent of a virtual copy ctor,
>>>>> and it would be simple to add to C++. Of course it would be totally
>>>>> nonlogical to allow virtual on exactly the copy ctor but in practice =
it
>>>>> would feel right, I think.
>>>>>
>>>>>
>>>>> If you have a type hierarchy that can do polymorphic copies (via a
>>>>> virtual clone() or some such), then
>>>>> you can make it work. Other than that, the issue is exactly the same
>>>>> as with shared_ptr, even though
>>>>> shared_ptr doesn't clone. To explain how it's exactly the same issue
>>>>> with shared_ptr, consider:
>>>>>
>>>>> struct B {}; // note, no virtual destructor
>>>>> struct D : B {~D();};
>>>>>
>>>>> int main()
>>>>> {
>>>>> shared_ptr<B> b{new D()}; // this works fine
>>>>> B* b2 =3D new D();
>>>>> shared_ptr<B> b3{b2}; // this doesn't work
>>>>> }
>>>>>
>>>>> It's not an issue with cloning. It's an issue with type erasure. If
>>>>> you create a cloned_ptr<B>
>>>>> from a B*, all knowledge of the fact that the B* was actually really =
a
>>>>> D* has been lost already.
>>>>>
>>>> --
>>>>
>>>> ---
>>>> 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-proposal...@isocpp.org.
>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>> Visit this group at
>>>> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>>
>>>
>>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> email to std-proposal...@isocpp.org.
>> To post to this group, send email to std-pr...@isocpp.org.
>> Visit this group at
>> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--001a11454ffacba3d30528efa78e
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 9 January 2016 at 23:33, Bengt Gustafsson <span dir=3D"=
ltr"><<a href=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank"=
>bengt.gustafsson@beamways.com</a>></span> wrote:<br><div class=3D"gmail=
_extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">No it=
's not: the offset addition that it has to do to convert from U to T in=
get() may differ (using the tpl parameter names of your code). The problem=
is not in copy() itself but in that copy instates an inner object with the=
wrong T in the receiving object, and the offset to add depends on the T an=
d U combination: Wrong T, potentially wrong offset. (I hope I'm wrong h=
ere but you haven't convinced me yet).<div><br></div><div>Why don't=
you settle this by testing? If you can't get it to fail I will give it=
a shot tomorrow, to late now.</div><div><div><br></div></div></div></block=
quote><div><br></div><div>I have settled this by testing. You are correct.<=
/div><br>I've restricted my design, following Germ=C3=A1n Diago's e=
xample, somewhat so that copies and assignment from different types cannot =
take place. This resolves "Gustafsson's dilemma" albeit somew=
hat unsatisfactorarily. The restricted design is still fit for my original =
purpose. I'll add notes on this to the draft proposal. Thanks for your =
continued interest and contribution.</div><div class=3D"gmail_quote"><div>=
=C2=A0</div><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-left-s=
tyle:solid;padding-left:1ex"><div dir=3D"ltr"><div><div>Den l=C3=B6rdag 9 j=
anuari 2016 kl. 21:06:38 UTC+1 skrev Jonathan Coe:<div><div class=3D"h5"><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pad=
ding-left:1ex"><div dir=3D"auto"><div></div><div><br></div><div><br>On 9 Ja=
n 2016, at 18:47, Bengt Gustafsson <<a rel=3D"nofollow">bengt.gu...@beam=
ways.com</a>> wrote:<br><br></div><blockquote type=3D"cite"><div><div di=
r=3D"ltr">Regarding the problems with multiple inheritance:<div><br></div><=
div>the general problem with multiple inheritance is that casting between b=
ase and subclass can involve addition of an offset to the this pointer.</di=
v><div><br></div><div>A naive inplementation of clone_ptr would create an i=
nner object (in your parlance) which contains a T* to the original T and a =
copy constructor calling virtual method. When the original deep_ptr<T>=
; is assigned into another deep_ptr<T2> =C2=A0where T2 is the second =
base of T the get() of the cloned inner object would still return the non-o=
ffsetted T* which does not point at the T2 part, and fails.</div><div><br><=
/div><div>Your implementation is better than this, which is possible as the=
operator=3D between deep_ptr<T> and deep_ptr<T2> knows of both=
these types and creates not a plain clone of the incoming inner object but=
a deep_ptr<T2>::inner<T> object, which knows how to do the cas=
t.</div><div><br></div><div>However, on the second copy to a new deep_prt&l=
t;T3> which has some other offset of pointers there is a bad thing happe=
ning. In your case this is in (for instance) when you do</div><div><br></di=
v><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;back=
ground-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,0)">=
=C2=A0</span><span style=3D"color:rgb(0,0,136)">reinterpret_cast</span><spa=
n style=3D"color:rgb(102,102,0)"><</span><span style=3D"color:rgb(0,0,13=
6)">const</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"col=
or:rgb(0,0,136)">typename</span><span style=3D"color:rgb(0,0,0)"> deep_ptr<=
/span><span style=3D"color:rgb(102,102,0)"><</span><span style=3D"color:=
rgb(0,0,0)">U</span><span style=3D"color:rgb(102,102,0)">>::</span><span=
style=3D"color:rgb(0,0,0)">inner </span><span style=3D"color:rgb(102,102,0=
)">*>(&</span><span style=3D"color:rgb(0,0,0)">u</span><span style=
=3D"color:rgb(102,102,0)">.</span><span style=3D"color:rgb(0,0,0)">buffer_<=
/span><span style=3D"color:rgb(102,102,0)">)-></span><span style=3D"colo=
r:rgb(0,0,0)">copy</span><span style=3D"color:rgb(102,102,0)">(&</span>=
<span style=3D"color:rgb(0,0,0)">buffer_</span><span style=3D"color:rgb(102=
,102,0)">);</span><span style=3D"color:rgb(0,0,0)"><br></span></div></code>=
</div><div><table style=3D"border-collapse:collapse;color:rgb(51,51,51);fon=
t-family:Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-ser=
if,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbo=
l';line-height:18.2px"><tbody><tr><td style=3D"padding-right:10px;paddi=
ng-left:10px;vertical-align:top;font-family:Consolas,'Liberation Mono&#=
39;,Menlo,Courier,monospace;font-size:12px;white-space:pre-wrap;overflow:vi=
sible;word-wrap:normal"><br></td></tr></tbody></table>This copy() call caus=
es a new deep_prt<T2>::inner_impl<T>() to be created rather tha=
n the deep_ptr<T3>::inner_impl<T> that is required. This will c=
reate an offsetting error when get() is called, or with virtual bases, wors=
e. Unfortunately I can't see a way around this problem, except doing so=
me offset arithmetic to sum up all the differences in the different copy st=
eps, and this still doesn't handle virtual base classes.</div><div><br>=
</div></div></div></blockquote><div><br></div><div>I don't think I see =
the problem.</div><div>deep_ptr<A>::inner_impl<T> is the same f=
or any choice of A. The important type info is T which is retained. If T ha=
s multiple virtual bases then it knows how to apply offsets to return point=
ers correctly. The choice of A has no bearing on this.=C2=A0</div><div><br>=
</div><div>I'll add Gustaffsons-dilemma as a test case.</div><br><block=
quote type=3D"cite"><div><div dir=3D"ltr"><div>to try to make this more und=
erstandable, in this code the erroneous vtbl is inserted:</div><div><br></d=
iv><div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-wor=
d;background-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,=
0,0)"><br></span><span style=3D"color:rgb(0,0,136)">void</span><span style=
=3D"color:rgb(0,0,0)"> copy</span><span style=3D"color:rgb(102,102,0)">(</s=
pan><span style=3D"color:rgb(0,0,136)">void</span><span style=3D"color:rgb(=
0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">*</span><span style=3D=
"color:rgb(0,0,0)">buffer</span><span style=3D"color:rgb(102,102,0)">)</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">const</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"colo=
r:rgb(0,0,136)">override</span><span style=3D"color:rgb(0,0,0)"> </span><sp=
an style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)">=
<br>=C2=A0</span><span style=3D"color:rgb(0,0,136)">new</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">(</span>=
<span style=3D"color:rgb(0,0,0)">buffer</span><span style=3D"color:rgb(102,=
102,0)">)</span><span style=3D"color:rgb(0,0,0)"> inner_impl</span><span st=
yle=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">new=
</span><span style=3D"color:rgb(0,0,0)"> U</span><span style=3D"color:rgb(1=
02,102,0)">(*</span><span style=3D"color:rgb(0,0,0)">u_</span><span style=
=3D"color:rgb(102,102,0)">));</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0</span><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"co=
lor:rgb(0,0,0)"> <br></span></div></code></div><table style=3D"border-colla=
pse:collapse;color:rgb(51,51,51);font-family:Helvetica,arial,nimbussansl,li=
berationsans,freesans,clean,sans-serif,'Apple Color Emoji','Seg=
oe UI Emoji','Segoe UI Symbol';line-height:18.2px"><tbody><tr><=
td style=3D"padding-right:10px;padding-left:10px;vertical-align:top;font-fa=
mily:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:1=
2px;white-space:pre-wrap;overflow:visible;word-wrap:normal"><br>
</td></tr></tbody></table>This code is called in the inner object inside th=
e deep_ptr<T2> but with the buffer pointing to the member of the deep=
_prt<T3> so when the get() method does its reinterpret_cast in:</div>=
<div><br></div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:br=
eak-word;background-color:rgb(250,250,250)"><code><div><span style=3D"color=
:rgb(0,0,0)">=C2=A0</span><span style=3D"color:rgb(0,0,136)">const</span><s=
pan style=3D"color:rgb(0,0,0)"> T </span><span style=3D"color:rgb(102,102,0=
)">*</span><span style=3D"color:rgb(0,0,136)">get</span><span style=3D"colo=
r:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span s=
tyle=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rgb(0,0,0)"> <=
/span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb=
(0,0,0)"><br>=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:rgb(0,0,136)">=
return</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(0,0,136)">reinterpret_cast</span><span style=3D"color:rgb(102,102,0)">&=
lt;</span><span style=3D"color:rgb(0,0,136)">const</span><span style=3D"col=
or:rgb(0,0,0)"> inner </span><span style=3D"color:rgb(102,102,0)">*>(&am=
p;</span><span style=3D"color:rgb(0,0,0)">buffer_</span><span style=3D"colo=
r:rgb(102,102,0)">)-></span><span style=3D"color:rgb(0,0,136)">get</span=
><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:rgb(0,=
0,0)"><br>=C2=A0</span><span style=3D"color:rgb(102,102,0)">}</span><span s=
tyle=3D"color:rgb(0,0,0)"><br><br></span></div></code></div><div>It erroneo=
usly casts a deep_ptr<T2>::inner to a deep_ptr<T3>::inner, thus=
misinterpreting the T2* that the inner object returns as a T3* with the of=
fset error as result.</div><div><br></div><div>This is what I think wlil ha=
ppen, I haven't actually tested it and it is really tricky code... I ho=
pe it works better! Also it seems that the current shared_ptr would have th=
e same issue which someone surely would have discovered by now... still I c=
an't figure out how to get around it.</div><div><br></div><div><br></di=
v><div><br>Den l=C3=B6rdag 9 januari 2016 kl. 00:58:07 UTC+1 skrev Jonathan=
Coe:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:so=
lid;padding-left:1ex"><div dir=3D"ltr"><br><div><br><div class=3D"gmail_quo=
te">On 8 January 2016 at 23:31, Bengt Gustafsson <span dir=3D"ltr"><<a r=
el=3D"nofollow">bengt.gu...@beamways.com</a>></span> wrote:<br><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-widt=
h:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-le=
ft:1ex"><div dir=3D"ltr">Of course, but it is stlil a big difference in tha=
t you can easily add a virtual destructor to the baseclass and then it will=
automatically work for all subclasses. If you just adhere to this shufflin=
g around the pointee between different shared_ptr instances is ok. And it w=
as my bad not to include a virtual destructor in my example. What I wanted =
to show was that cloning could never work even with this in place (just as =
you remarked).<div><br></div><div>As for your shared_ptr example (as an asi=
de), wouldn't it be nice to be able to flag that using a trait has_virt=
ual_dtor<T> (needed on both types when doing a cross-type assignment =
between shared_ptrs). I guess this could break some code, but more often wo=
uld reveal bugs not hitherto detected...<br><div><br><div>After reading Jon=
athans implementation I doubt that this can even work for the multiple-inhe=
ritance case. I don't mean just his code but in general: The U* inside =
the inner<U> object gets properly cast after the first copy operation=
, but after the second copying it wont, as the creation of the third inner =
object gets the template parameter of the second, not the first. It's l=
ate now and I may not be thinking straight, but at this point I think it is=
impossible (for multiple inheritance) without help from the pointee.</div>=
<div><span><br></span></div></div></div></div></blockquote><div><br></div><=
div>If construction is only possible through a factory method, then the sta=
tic type and dynamic type of the object must be the same.=C2=A0</div><div><=
br></div><div>To clarify, your earlier example was of a pointer whose dynam=
ic type differed from the static type used in the pointer constructor.</div=
><div><br></div><div><span style=3D"font-family:monospace;font-size:10px;co=
lor:rgb(102,0,102)">1 Base</span><span style=3D"font-family:monospace;font-=
size:10px;color:rgb(102,102,0)">*</span><span style=3D"font-family:monospac=
e;font-size:10px;color:rgb(0,0,0)">=C2=A0b=C2=A0</span><span style=3D"font-=
family:monospace;font-size:10px;color:rgb(102,102,0)">=3D</span><span style=
=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0</span><sp=
an style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,136)">new</s=
pan><span style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=
=C2=A0</span><span style=3D"font-family:monospace;font-size:10px;color:rgb(=
102,0,102)">Sub</span><span style=3D"font-family:monospace;font-size:10px;c=
olor:rgb(102,102,0)">;</span><span style=3D"font-family:monospace;font-size=
:10px;color:rgb(0,0,0)"><br>2 clone_ptr</span><span style=3D"font-family:mo=
nospace;font-size:10px;color:rgb(102,102,0)"><</span><span style=3D"font=
-family:monospace;font-size:10px;color:rgb(102,0,102)">Base</span><span sty=
le=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0)">></span=
><span style=3D"font-family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=
=A0p=C2=A0</span><span style=3D"font-family:monospace;font-size:10px;color:=
rgb(102,102,0)">=3D</span><span style=3D"font-family:monospace;font-size:10=
px;color:rgb(0,0,0)">=C2=A0b</span><span style=3D"font-family:monospace;fon=
t-size:10px;color:rgb(102,102,0)">;</span><span style=3D"font-family:monosp=
ace;font-size:10px;color:rgb(0,0,0)"><br>3 clone_ptr</span><span style=3D"f=
ont-family:monospace;font-size:10px;color:rgb(102,102,0)"><</span><span =
style=3D"font-family:monospace;font-size:10px;color:rgb(102,0,102)">Base</s=
pan><span style=3D"font-family:monospace;font-size:10px;color:rgb(102,102,0=
)">></span><span style=3D"font-family:monospace;font-size:10px;color:rgb=
(0,0,0)">=C2=A0p2=C2=A0</span><span style=3D"font-family:monospace;font-siz=
e:10px;color:rgb(102,102,0)">=3D</span><span style=3D"font-family:monospace=
;font-size:10px;color:rgb(0,0,0)">=C2=A0p</span><span style=3D"font-family:=
monospace;font-size:10px;color:rgb(102,102,0)">;</span><span style=3D"font-=
family:monospace;font-size:10px;color:rgb(0,0,0)">=C2=A0=C2=A0</span><br></=
div><div><br></div><div>I do not allow assignment or construction from raw =
pointers, only from deep_ptrs (clone_ptrs) so line 2 will not compile.</div=
><div><br></div><div>I don't see how multiple inheritance complicates t=
his, can you elaborate?<br></div><div>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-lef=
t-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div><div><span><br>Den fredag 8 januari 2016 kl. 21:25:57 UT=
C+1 skrev Ville Voutilainen:</span><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><span>On 8 January 201=
6 at 22:17, Bengt Gustafsson
<br></span><div><div><<a rel=3D"nofollow">bengt.gu...@beamways.com</a>&g=
t; wrote:
<br>> Nevin: The deep_ptr is supposed to clone the pointee which the sha=
red_ptr never does. That's the problem here: How can the exact subclass=
of the pointee be known at the later time when the cloning is to take plac=
e.
<br>>
<br>> Many other languages support the eqivalent of a virtual copy ctor,=
and it would be simple to add to C++. Of course it would be totally nonlog=
ical to allow virtual on exactly the copy ctor but in practice it would fee=
l right, I think.
<br>
<br>
<br>If you have a type hierarchy that can do polymorphic copies (via a
<br>virtual clone() or some such), then
<br>you can make it work. Other than that, the issue is exactly the same
<br>as with shared_ptr, even though
<br>shared_ptr doesn't clone. To explain how it's exactly the same =
issue
<br>with shared_ptr, consider:
<br>
<br>struct B {}; =C2=A0// note, no virtual destructor
<br>struct D : B {~D();};
<br>
<br>int main()
<br>{
<br>=C2=A0 =C2=A0 shared_ptr<B> b{new D()}; // this works fine
<br>=C2=A0 =C2=A0 B* b2 =3D new D();
<br>=C2=A0 =C2=A0 shared_ptr<B> b3{b2}; // this doesn't work
<br>}
<br>
<br>It's not an issue with cloning. It's an issue with type erasure=
.. If
<br>you create a cloned_ptr<B>
<br>from a B*, all knowledge of the fact that the B* was actually really a
<br>D* has been lost already.
<br></div></div></blockquote></div></div></div></div><div><div>
<p></p>
-- <br>
<br>
--- <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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"nofollow" target=3D"_blank">https://groups.google.c=
om/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
</blockquote></div></div>
<p></p>
-- <br>
<br>
--- <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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"nofollow" target=3D"_blank">https://groups.google.c=
om/a/isocpp.org/group/std-proposals/</a>.<br>
</div></blockquote></div></blockquote></div></div></div></div></div><div cl=
ass=3D""><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a11454ffacba3d30528efa78e--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 02:21:23 +0200
Raw View
--001a1140f52ce6b1170528efcc98
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On 10 January 2016 at 02:11, Jonathan Coe <jbcoe@me.com> wrote:
> Why don't you settle this by testing? If you can't get it to fail I will
> give it a shot tomorrow, to late now.
>
>>
>>
> I have settled this by testing. You are correct.
>
> I've restricted my design, following Germ=C3=A1n Diago's example, somewha=
t so
> that copies and assignment from different types cannot take place. This
> resolves "Gustafsson's dilemma" albeit somewhat unsatisfactorarily. The
> restricted design is still fit for my original purpose. I'll add notes on
> this to the draft proposal. Thanks for your continued interest and
> contribution.
>
So, are you saying that the test at the end of
https://github.com/jbcoe/deep_ptr/blob/master/TestDeepPtr.cpp
fails with your implementation?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--001a1140f52ce6b1170528efcc98
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On 10 January 2016 at 02:11, Jonathan Coe <span dir=3D"ltr"><<a href=
=3D"mailto:jbcoe@me.com" target=3D"_blank">jbcoe@me.com</a>></span> wrot=
e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><s=
pan class=3D""></span>Why don't you settle this by testing? If you can&=
#39;t get it to fail I will give it a shot tomorrow, to late now.<div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D""><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid=
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div><br></div></=
div></div></blockquote><div><br></div></span><div>I have settled this by te=
sting. You are correct.</div><br>I've restricted my design, following G=
erm=C3=A1n Diago's example, somewhat so that copies and assignment from=
different types cannot take place. This resolves "Gustafsson's di=
lemma" albeit somewhat unsatisfactorarily. The restricted design is st=
ill fit for my original purpose. I'll add notes on this to the draft pr=
oposal. Thanks for your continued interest and contribution.</div></div></d=
iv></blockquote><div><br></div><div>So, are you saying that the test at the=
end of<br>=C2=A0<a href=3D"https://github.com/jbcoe/deep_ptr/blob/master/T=
estDeepPtr.cpp">https://github.com/jbcoe/deep_ptr/blob/master/TestDeepPtr.c=
pp</a> <br></div><div>fails with your implementation?<br></div></div></div>=
</div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a1140f52ce6b1170528efcc98--
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 10 Jan 2016 18:36:02 +0800
Raw View
--Apple-Mail=_7F16A27E-CA12-4D10-A9F9-A75C7D74F588
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2016=E2=80=9301=E2=80=9310, at 7:49 AM, Ville Voutilainen <ville.vouti=
lainen@gmail.com> wrote:
>=20
> The offset depends on the call entry's type(*) and the covariant type the=
type-erased override
> actually returns. shared_ptr works fine with the case you think is proble=
matic, because
> the offset is adjusted at run-time. I don't know whether Jonathan's imple=
mentation gets it
> right with its reinterpret_cast dance, but shared_ptr and my implementati=
on do.
shared_ptr stores the pointer to the complete object (or the value provided=
along with a custom deleter) in the control block. The result of get() is =
exactly the one stored locally in the shared_ptr object, and the argument t=
o the deleter is exactly the control block slot. Neither ever gets an offse=
t adjustment, and there need not be any relationship at all between the two=
pointer values.
Like shared_ptr, value_ptr type-erases its deleter, meaning it potentially =
goes on the heap. So the value_ptr class certainly needs a pointer to a pri=
vate heap block. I think it would save a lot of trouble to let value_ptr wo=
rk like a shared_ptr with a reference count fixed at 1, and cloning functio=
nality tacked on. Specifically, cache the value of get(), and put a heap-al=
located control block in charge of destruction and cloning. Then,
=E2=80=94 sizeof(value_ptr<T>)=3D=3D2*sizeof(void*), which is the minimum.
=E2=80=94 get() is implemented by a single fetch instruction.
=E2=80=94 There=E2=80=99s room for all the type-erasure you might want.
=E2=80=94 In the common case of no casts and no custom allocator/deleter, t=
he control block pointer can be nullptr, and fall back to default behavior.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--Apple-Mail=_7F16A27E-CA12-4D10-A9F9-A75C7D74F588
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2016=E2=80=9301=
=E2=80=9310, at 7:49 AM, Ville Voutilainen <<a href=3D"mailto:ville.vout=
ilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</d=
iv><br class=3D"Apple-interchange-newline"><div class=3D""><div style=3D"fo=
nt-family: Helvetica; font-size: 12px; font-style: normal; font-variant: no=
rmal; font-weight: normal; letter-spacing: normal; orphans: auto; text-alig=
n: start; text-indent: 0px; text-transform: none; white-space: normal; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"">Th=
e offset depends on the call entry's type(*) and the covariant type the typ=
e-erased override<br class=3D""></div><div style=3D"font-family: Helvetica;=
font-size: 12px; font-style: normal; font-variant: normal; font-weight: no=
rmal; letter-spacing: normal; orphans: auto; text-align: start; text-indent=
: 0px; text-transform: none; white-space: normal; widows: auto; word-spacin=
g: 0px; -webkit-text-stroke-width: 0px;" class=3D"">actually returns. share=
d_ptr works fine with the case you think is problematic, because<br class=
=3D""></div><div style=3D"font-family: Helvetica; font-size: 12px; font-sty=
le: normal; font-variant: normal; font-weight: normal; letter-spacing: norm=
al; orphans: auto; text-align: start; text-indent: 0px; text-transform: non=
e; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-strok=
e-width: 0px;" class=3D"">the offset is adjusted at run-time. I don't know =
whether Jonathan's implementation gets it<br class=3D""></div><div style=3D=
"font-family: Helvetica; font-size: 12px; font-style: normal; font-variant:=
normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-a=
lign: start; text-indent: 0px; text-transform: none; white-space: normal; w=
idows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""=
>right with its reinterpret_cast dance, but shared_ptr and my implementatio=
n do.<br class=3D""></div></div></blockquote></div><br class=3D""><div clas=
s=3D""><font face=3D"Courier" class=3D"">shared_ptr</font> stores the point=
er to the complete object (or the value provided along with a custom delete=
r) in the control block. The result of <font face=3D"Courier" class=3D"">ge=
t()</font> is exactly the one stored locally in the <font face=3D"Cour=
ier" class=3D"">shared_ptr</font> object, and the argument to the deleter i=
s exactly the control block slot. Neither ever gets an offset adjustment, a=
nd there need not be any relationship at all between the two pointer values=
..</div><div class=3D""><br class=3D""></div><div class=3D"">Like <font face=
=3D"Courier" class=3D"">shared_ptr</font>, <font face=3D"Courier" class=3D"=
">value_ptr</font> type-erases its deleter, meaning it potentially goes on =
the heap. So the <span style=3D"font-family: Courier;" class=3D"">valu=
e_ptr</span> class certainly needs a pointer to a private heap block. =
I think it would save a lot of trouble to let <font face=3D"Courier" class=
=3D"">value_ptr</font> work like a <font face=3D"Courier" class=3D"">shared=
_ptr</font> with a reference count fixed at 1, and cloning functionality ta=
cked on. Specifically, cache the value of <font face=3D"Courier" class=3D""=
>get()</font>, and put a heap-allocated control block in charge of destruct=
ion and cloning. Then,</div><div class=3D""><br class=3D""></div><div class=
=3D"">=E2=80=94 <font face=3D"Courier" class=3D"">sizeof(value_ptr<=
;T>)=3D=3D2*sizeof(void*)</font>, which is the minimum.</div><div class=
=3D"">=E2=80=94 <font face=3D"Courier" class=3D"">get()</font> is implement=
ed by a single fetch instruction.</div><div class=3D"">=E2=80=94 There=E2=
=80=99s room for all the type-erasure you might want.</div><div class=3D"">=
=E2=80=94 In the common case of no casts and no custom allocator/deleter, t=
he control block pointer can be <font face=3D"Courier" class=3D"">nullptr</=
font>, and fall back to default behavior.</div><div class=3D""><br class=3D=
""></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail=_7F16A27E-CA12-4D10-A9F9-A75C7D74F588--
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sun, 10 Jan 2016 10:39:10 +0000
Raw View
--047d7b86eaac46dbd60528f86eb7
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On 10 January 2016 at 00:21, Ville Voutilainen <ville.voutilainen@gmail.com=
>
wrote:
>
>
> On 10 January 2016 at 02:11, Jonathan Coe <jbcoe@me.com> wrote:
>
>> Why don't you settle this by testing? If you can't get it to fail I will
>> give it a shot tomorrow, to late now.
>>
>>>
>>>
>> I have settled this by testing. You are correct.
>>
>> I've restricted my design, following Germ=C3=A1n Diago's example, somewh=
at so
>> that copies and assignment from different types cannot take place. This
>> resolves "Gustafsson's dilemma" albeit somewhat unsatisfactorarily. The
>> restricted design is still fit for my original purpose. I'll add notes o=
n
>> this to the draft proposal. Thanks for your continued interest and
>> contribution.
>>
>
> So, are you saying that the test at the end of
> https://github.com/jbcoe/deep_ptr/blob/master/TestDeepPtr.cpp
> fails with your implementation?
>
The test 'Gustafssons dilemma' breaks with my implementation in version
643d9635b2895f7bb77dc4fb9e9597c1b358a4e4.
https://github.com/jbcoe/deep_ptr/tree/643d9635b2895f7bb77dc4fb9e9597c1b358=
a4e4
It's not clear to me why this breaks.
I don't need the ability to construct/assign derived-type deep_ptrs from
base-type deep_ptr so have removed this functionality from my newer simpler
implementation (no buffer).
https://github.com/jbcoe/deep_ptr/tree/827bfaadff635f4b1bcb9e13ec013187150b=
8ce9
It would be useful to understand which limitations are fundamental and
which are facets of the implementation.
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--047d7b86eaac46dbd60528f86eb7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On 10 January 2016 at 00:21, Ville Voutilainen <span dir=3D"ltr"><<a=
href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutil=
ainen@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:r=
gb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">=
<br><div class=3D"gmail_extra"><br><div class=3D"gmail_quote"><span class=
=3D"">On 10 January 2016 at 02:11, Jonathan Coe <span dir=3D"ltr"><<a hr=
ef=3D"mailto:jbcoe@me.com" target=3D"_blank">jbcoe@me.com</a>></span> wr=
ote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,20=
4,204);padding-left:1ex"><div dir=3D"ltr"><span></span>Why don't you se=
ttle this by testing? If you can't get it to fail I will give it a shot=
tomorrow, to late now.<div class=3D"gmail_extra"><div class=3D"gmail_quote=
"><span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,20=
4,204);padding-left:1ex"><div dir=3D"ltr"><div><div><br></div></div></div><=
/blockquote><div><br></div></span><div>I have settled this by testing. You =
are correct.</div><br>I've restricted my design, following Germ=C3=A1n =
Diago's example, somewhat so that copies and assignment from different =
types cannot take place. This resolves "Gustafsson's dilemma"=
albeit somewhat unsatisfactorarily. The restricted design is still fit for=
my original purpose. I'll add notes on this to the draft proposal. Tha=
nks for your continued interest and contribution.</div></div></div></blockq=
uote><div><br></div></span><div>So, are you saying that the test at the end=
of<br>=C2=A0<a href=3D"https://github.com/jbcoe/deep_ptr/blob/master/TestD=
eepPtr.cpp" target=3D"_blank">https://github.com/jbcoe/deep_ptr/blob/master=
/TestDeepPtr.cpp</a> <br></div><div>fails with your implementation?</div></=
div></div></div></blockquote><br>The test 'Gustafssons dilemma' bre=
aks with my implementation in version 643d9635b2895f7bb77dc4fb9e9597c1b358a=
4e4.</div><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quote"><=
a href=3D"https://github.com/jbcoe/deep_ptr/tree/643d9635b2895f7bb77dc4fb9e=
9597c1b358a4e4">https://github.com/jbcoe/deep_ptr/tree/643d9635b2895f7bb77d=
c4fb9e9597c1b358a4e4</a><br></div><div class=3D"gmail_quote"><br></div><div=
class=3D"gmail_quote">It's not clear to me why this breaks.=C2=A0</div=
><div class=3D"gmail_quote"><br></div><div class=3D"gmail_quote">I don'=
t need the ability to construct/assign derived-type deep_ptrs from base-typ=
e deep_ptr so have removed this functionality from my newer simpler impleme=
ntation (no buffer).=C2=A0<br></div><div class=3D"gmail_quote"><div>=C2=A0<=
/div><div><a href=3D"https://github.com/jbcoe/deep_ptr/tree/827bfaadff635f4=
b1bcb9e13ec013187150b8ce9">https://github.com/jbcoe/deep_ptr/tree/827bfaadf=
f635f4b1bcb9e13ec013187150b8ce9</a><br></div><div><br></div><div>It would b=
e useful to understand which limitations are fundamental and which are face=
ts of the implementation.</div><div><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-co=
lor:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=
=3D""><div class=3D"h5">
<br>
--- <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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7b86eaac46dbd60528f86eb7--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 16:07:21 +0200
Raw View
On 10 January 2016 at 12:39, Jonathan Coe <jbcoe@me.com> wrote:
> The test 'Gustafssons dilemma' breaks with my implementation in version
> 643d9635b2895f7bb77dc4fb9e9597c1b358a4e4.
>
> https://github.com/jbcoe/deep_ptr/tree/643d9635b2895f7bb77dc4fb9e9597c1b358a4e4
>
> It's not clear to me why this breaks.
>
> I don't need the ability to construct/assign derived-type deep_ptrs from
> base-type deep_ptr so have removed this functionality from my newer simpler
> implementation (no buffer).
Well, while that's backwards (such a conversion requires a cast, quite
like static_pointer_cast),
conversions from derived-type pointers to base-type pointers should work.
> https://github.com/jbcoe/deep_ptr/tree/827bfaadff635f4b1bcb9e13ec013187150b8ce9
> It would be useful to understand which limitations are fundamental and which
> are facets of the implementation.
That particilar breakage is due to your implementation. The test works
with the approach
I have.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 16:12:51 +0200
Raw View
On 10 January 2016 at 12:36, David Krauss <potswa@gmail.com> wrote:
> shared_ptr stores the pointer to the complete object (or the value provided
> along with a custom deleter) in the control block. The result of get() is
> exactly the one stored locally in the shared_ptr object, and the argument to
> the deleter is exactly the control block slot. Neither ever gets an offset
> adjustment, and there need not be any relationship at all between the two
> pointer values.
The offset adjustment happens in get().
> Like shared_ptr, value_ptr type-erases its deleter, meaning it potentially
> goes on the heap. So the value_ptr class certainly needs a pointer to a
> private heap block. I think it would save a lot of trouble to let value_ptr
> work like a shared_ptr with a reference count fixed at 1, and cloning
> functionality tacked on.
That's what my current implementation does...
>Specifically, cache the value of get(), and put a
....although I don't know why this bit would be significant.
What I'm currently looking at is the annoyance of having to dynamically allocate
a delegating cloner, which wraps the incoming cloner. That delegating cloner
is what makes the conversions work, since it'll delegate cloning/deleting a B*
to a cloner that wants a D*. Having all the allocations of the cloner
it self performed
by the cloner is straightforward, having the allocation of the delegating cloner
not so much. Solving that problem would bring forth complete minimal allocator
support.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 10 Jan 2016 22:34:12 +0800
Raw View
--Apple-Mail=_A73285E9-8BEA-4667-8384-BE03FB654504
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2016=E2=80=9301=E2=80=9310, at 10:12 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com> wrote:
>=20
> On 10 January 2016 at 12:36, David Krauss <potswa@gmail.com> wrote:
>> shared_ptr stores the pointer to the complete object (or the value provi=
ded
>> along with a custom deleter) in the control block. The result of get() i=
s
>> exactly the one stored locally in the shared_ptr object, and the argumen=
t to
>> the deleter is exactly the control block slot. Neither ever gets an offs=
et
>> adjustment, and there need not be any relationship at all between the tw=
o
>> pointer values.
>=20
> The offset adjustment happens in get().
Here=E2=80=99s libc++ shared_ptr::get: https://github.com/llvm-mirror/libcx=
x/blob/master/include/memory#L2714 <https://github.com/llvm-mirror/libcxx/b=
lob/master/include/memory#L2714>
Here=E2=80=99s libstdc++: https://github.com/gcc-mirror/gcc/blob/master/lib=
stdc%2B%2B-v3/include/bits/shared_ptr_base.h#L1063 <https://github.com/gcc-=
mirror/gcc/blob/master/libstdc++-v3/include/bits/shared_ptr_base.h#L1063>
There=E2=80=99s no casting. Perhaps you=E2=80=99re thinking of something ot=
her than shared_ptr?
>> Like shared_ptr, value_ptr type-erases its deleter, meaning it potential=
ly
>> goes on the heap. So the value_ptr class certainly needs a pointer to a
>> private heap block. I think it would save a lot of trouble to let value_=
ptr
>> work like a shared_ptr with a reference count fixed at 1, and cloning
>> functionality tacked on.
>=20
> That's what my current implementation does...
>=20
>> Specifically, cache the value of get(), and put a
>=20
> ...although I don't know why this bit would be significant.
It saves a trip through type erasure.
> What I'm currently looking at is the annoyance of having to dynamically a=
llocate
> a delegating cloner, which wraps the incoming cloner. That delegating clo=
ner
> is what makes the conversions work, since it'll delegate cloning/deleting=
a B*
> to a cloner that wants a D*.
Use a std::function inside the control block. A chain of conversions might =
entail a nested chain of std::functions. There are optimizations: you could=
be fancy and collapse the chain for simple offset arithmetic. Eliminate th=
e entire control block and use static defaults for the common case of no co=
nversion or customization, as I mentioned. But, I=E2=80=99d implement the g=
eneral case first and optimize after.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--Apple-Mail=_A73285E9-8BEA-4667-8384-BE03FB654504
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2016=E2=80=9301=
=E2=80=9310, at 10:12 PM, Ville Voutilainen <<a href=3D"mailto:ville.vou=
tilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</=
div><br class=3D"Apple-interchange-newline"><div class=3D""><div class=3D""=
>On 10 January 2016 at 12:36, David Krauss <<a href=3D"mailto:potswa@gma=
il.com" class=3D"">potswa@gmail.com</a>> wrote:<br class=3D""><blockquot=
e type=3D"cite" class=3D"">shared_ptr stores the pointer to the complete ob=
ject (or the value provided<br class=3D"">along with a custom deleter) in t=
he control block. The result of get() is<br class=3D"">exactly the one stor=
ed locally in the shared_ptr object, and the argument to<br class=3D"">the =
deleter is exactly the control block slot. Neither ever gets an offset<br c=
lass=3D"">adjustment, and there need not be any relationship at all between=
the two<br class=3D"">pointer values.<br class=3D""></blockquote><br class=
=3D"">The offset adjustment happens in get().<br class=3D""></div></div></b=
lockquote><div><br class=3D""></div><div>Here=E2=80=99s libc++ shared_ptr::=
get: <a href=3D"https://github.com/llvm-mirror/libcxx/blob/master/incl=
ude/memory#L2714" class=3D"">https://github.com/llvm-mirror/libcxx/blob/mas=
ter/include/memory#L2714</a></div><div>Here=E2=80=99s libstdc++: <a hr=
ef=3D"https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/include/bi=
ts/shared_ptr_base.h#L1063" class=3D"">https://github.com/gcc-mirror/gcc/bl=
ob/master/libstdc%2B%2B-v3/include/bits/shared_ptr_base.h#L1063</a></div><d=
iv><br class=3D""></div><div>There=E2=80=99s no casting. Perhaps you=E2=80=
=99re thinking of something other than <font face=3D"Courier" class=3D"">sh=
ared_ptr</font>?</div><br class=3D""><blockquote type=3D"cite" class=3D""><=
div class=3D""><div class=3D""><blockquote type=3D"cite" class=3D"">Like sh=
ared_ptr, value_ptr type-erases its deleter, meaning it potentially<br clas=
s=3D"">goes on the heap. So the value_ptr class certainly needs a pointer t=
o a<br class=3D"">private heap block. I think it would save a lot of troubl=
e to let value_ptr<br class=3D"">work like a shared_ptr with a reference co=
unt fixed at 1, and cloning<br class=3D"">functionality tacked on.<br class=
=3D""></blockquote><br class=3D"">That's what my current implementation doe=
s...<br class=3D""><br class=3D""><blockquote type=3D"cite" class=3D"">Spec=
ifically, cache the value of get(), and put a<br class=3D""></blockquote><b=
r class=3D"">...although I don't know why this bit would be significant.<br=
class=3D""></div></div></blockquote><div><br class=3D""></div><div>It save=
s a trip through type erasure.</div><br class=3D""><blockquote type=3D"cite=
" class=3D""><div class=3D""><div class=3D"">What I'm currently looking at =
is the annoyance of having to dynamically allocate<br class=3D"">a delegati=
ng cloner, which wraps the incoming cloner. That delegating cloner<br class=
=3D"">is what makes the conversions work, since it'll delegate cloning/dele=
ting a B*<br class=3D"">to a cloner that wants a D*.</div></div></blockquot=
e><div><br class=3D""></div><div>Use a <font face=3D"Courier" class=3D=
"">std::function</font> inside the control block. A chain of conversio=
ns might entail a nested chain of <font face=3D"Courier" class=3D"">std::fu=
nction</font>s. There are optimizations: you could be fancy and collapse th=
e chain for simple offset arithmetic. Eliminate the entire control block an=
d use static defaults for the common case of no conversion or customization=
, as I mentioned. But, I=E2=80=99d implement the general case first and opt=
imize after.</div></div><div class=3D""><br class=3D""></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail=_A73285E9-8BEA-4667-8384-BE03FB654504--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 16:40:10 +0200
Raw View
On 10 January 2016 at 16:34, David Krauss <potswa@gmail.com> wrote:
> The offset adjustment happens in get().
>
> Here=E2=80=99s libc++ shared_ptr::get:
> https://github.com/llvm-mirror/libcxx/blob/master/include/memory#L2714
> Here=E2=80=99s libstdc++:
> https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bi=
ts/shared_ptr_base.h#L1063
I have no idea why you're pointing me to libc++'s unique_ptr.
> There=E2=80=99s no casting. Perhaps you=E2=80=99re thinking of something =
other than
> shared_ptr?
There's no casting, the conversion is implicit, and the covariant
return of the override
in the type-erased implementation does the adjustment.
> Specifically, cache the value of get(), and put a
>
>
> ...although I don't know why this bit would be significant.
>
>
> It saves a trip through type erasure.
Ah, so nothing significant design-wise.
>
> What I'm currently looking at is the annoyance of having to dynamically
> allocate
> a delegating cloner, which wraps the incoming cloner. That delegating clo=
ner
> is what makes the conversions work, since it'll delegate cloning/deleting=
a
> B*
> to a cloner that wants a D*.
>
>
> Use a std::function inside the control block. A chain of conversions migh=
t
That doesn't help.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 16:52:42 +0200
Raw View
On 10 January 2016 at 16:40, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 10 January 2016 at 16:34, David Krauss <potswa@gmail.com> wrote:
>> The offset adjustment happens in get().
>>
>> Here=E2=80=99s libc++ shared_ptr::get:
>> https://github.com/llvm-mirror/libcxx/blob/master/include/memory#L2714
>> Here=E2=80=99s libstdc++:
>> https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/b=
its/shared_ptr_base.h#L1063
>
> I have no idea why you're pointing me to libc++'s unique_ptr.
>
>> There=E2=80=99s no casting. Perhaps you=E2=80=99re thinking of something=
other than
>> shared_ptr?
>
> There's no casting, the conversion is implicit, and the covariant
> return of the override
> in the type-erased implementation does the adjustment.
Well, ok, libstdc++ shared_ptr does the offset adjustment when it
stores the incoming
pointer, and gives the original pointer to the refcount, which stores
that original pointer
and deleter, thus achieving the caching you mention below. So no need
to do it on every
get().
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 10 Jan 2016 23:04:01 +0800
Raw View
--Apple-Mail=_2D7D4F1A-DF1C-4126-BC1F-FB0E4C1E07DD
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2016=E2=80=9301=E2=80=9310, at 10:52 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com> wrote:
>=20
> Well, ok, libstdc++ shared_ptr does the offset adjustment when it
> stores the incoming
> pointer, and gives the original pointer to the refcount, which stores
> that original pointer
> and deleter, thus achieving the caching you mention below. So no need
> to do it on every
> get().
libc++ and libstdc++ work the same. If you use a converting constructor, th=
en that encapsulates a pointer conversion. If you use another overload [uti=
l.smartptr.shared.const] =C2=A720.8.2.2.1/13, then the =E2=80=9Ccached=E2=
=80=9D value is whatever you want it to be =E2=80=94 no pointer conversion =
or offset adjustment need exist. Such a constructor would be impossible for=
value_ptr, but reasonable parity could be achieved by a constructor taking=
an arbitrary functor (e.g. an accessor wrapped in a lambda) which is used =
per clone to generate cached pointers.
The lazy approach to value_ptr design would be to reuse shared_ptr implemen=
tation, and the results should be good. Or so I think. Maybe I=E2=80=99ll t=
ake a shot, but there are other things I should be doing now.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--Apple-Mail=_2D7D4F1A-DF1C-4126-BC1F-FB0E4C1E07DD
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2016=E2=80=9301=
=E2=80=9310, at 10:52 PM, Ville Voutilainen <<a href=3D"mailto:ville.vou=
tilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</=
div><br class=3D"Apple-interchange-newline"><div class=3D""><div class=3D""=
>Well, ok, libstdc++ shared_ptr does the offset adjustment when it<br class=
=3D"">stores the incoming<br class=3D"">pointer, and gives the original poi=
nter to the refcount, which stores<br class=3D"">that original pointer<br c=
lass=3D"">and deleter, thus achieving the caching you mention below. So no =
need<br class=3D"">to do it on every<br class=3D"">get().<br class=3D""></d=
iv></div></blockquote></div><br class=3D""><div class=3D"">libc++ and libst=
dc++ work the same. If you use a converting constructor, then that encapsul=
ates a pointer conversion. If you use another overload [util.smartptr.share=
d.const] =C2=A720.8.2.2.1/13, then the =E2=80=9Ccached=E2=80=9D value is wh=
atever you want it to be =E2=80=94 no pointer conversion or offset adjustme=
nt need exist. Such a constructor would be impossible for <font face=3D"Cou=
rier" class=3D"">value_ptr</font>, but reasonable parity could be achieved =
by a constructor taking an arbitrary functor (e.g. an accessor wrapped in a=
lambda) which is used per clone to generate cached pointers.</div><div cla=
ss=3D""><br class=3D""></div><div class=3D"">The lazy approach to <font fac=
e=3D"Courier" class=3D"">value_ptr</font> design would be to reuse <font fa=
ce=3D"Courier" class=3D"">shared_ptr</font> implementation, and the results=
should be good. Or so I think. Maybe I=E2=80=99ll take a shot, but there a=
re other things I should be doing now.</div><div class=3D""><br class=3D"">=
</div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail=_2D7D4F1A-DF1C-4126-BC1F-FB0E4C1E07DD--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 17:12:31 +0200
Raw View
On 10 January 2016 at 17:04, David Krauss <potswa@gmail.com> wrote:
>
> On 2016=E2=80=9301=E2=80=9310, at 10:52 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com>
> wrote:
>
> Well, ok, libstdc++ shared_ptr does the offset adjustment when it
> stores the incoming
> pointer, and gives the original pointer to the refcount, which stores
> that original pointer
> and deleter, thus achieving the caching you mention below. So no need
> to do it on every
> get().
>
>
> libc++ and libstdc++ work the same. If you use a converting constructor,
> then that encapsulates a pointer conversion. If you use another overload
> [util.smartptr.shared.const] =C2=A720.8.2.2.1/13, then the =E2=80=9Ccache=
d=E2=80=9D value is
> whatever you want it to be =E2=80=94 no pointer conversion or offset adju=
stment need
> exist. Such a constructor would be impossible for value_ptr, but reasonab=
le
Which part of it is impossible for value_ptr?
> parity could be achieved by a constructor taking an arbitrary functor (e.=
g.
> an accessor wrapped in a lambda) which is used per clone to generate cach=
ed
> pointers.
Sounds overly complicated. As long as the cloner has the original
pointer type, like
shared_ptr deleter does, it works just fine, and the 'cached' pointer
can be of the type
the topmost level expects.
>
> The lazy approach to value_ptr design would be to reuse shared_ptr
> implementation, and the results should be good. Or so I think. Maybe I=E2=
=80=99ll
> take a shot, but there are other things I should be doing now.
I already have a value_ptr that is using shared_ptr internally to do
type erasure.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 10 Jan 2016 23:40:16 +0800
Raw View
--Apple-Mail=_3FC6C122-44C5-46D5-B8B6-F37656984C28
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2016=E2=80=9301=E2=80=9310, at 11:12 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com> wrote:
>=20
> Which part of it is impossible for value_ptr?
The premise of shared_ptr<T>::shared_ptr(const shared_ptr<Y>& r, T* p) is t=
o pass a p which is owned by r. If the same thing were done for value_ptr, =
the clone of r wouldn=E2=80=99t own p. So the equivalent would instead be v=
alue_ptr<T>::value_ptr(const value_ptr<Y>& r, F f) where F is an accessor t=
aking Y* and returning T*. Complicated, maybe, but very general, since the =
various pointer conversions can be synthesized by F accessors.
>> The lazy approach to value_ptr design would be to reuse shared_ptr
>> implementation, and the results should be good. Or so I think. Maybe I=
=E2=80=99ll
>> take a shot, but there are other things I should be doing now.
>=20
> I already have a value_ptr that is using shared_ptr internally to do
> type erasure.
Hmm, so why not delegate value_ptr::get() to the encapsulated shared_ptr an=
d let it mediate between differing types? Guess I=E2=80=99d have to take a =
look. There are a bunch of things going on, I=E2=80=99m certainly not sayin=
g it=E2=80=99s trivial=E2=80=A6
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--Apple-Mail=_3FC6C122-44C5-46D5-B8B6-F37656984C28
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2016=E2=80=9301=
=E2=80=9310, at 11:12 PM, Ville Voutilainen <<a href=3D"mailto:ville.vou=
tilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</=
div><br class=3D"Apple-interchange-newline"><div class=3D""><span style=3D"=
font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: =
normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-al=
ign: start; text-indent: 0px; text-transform: none; white-space: normal; wi=
dows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none;=
display: inline !important;" class=3D"">Which part of it is impossible for=
value_ptr?</span><br style=3D"font-family: Helvetica; font-size: 12px; fon=
t-style: normal; font-variant: normal; font-weight: normal; letter-spacing:=
normal; orphans: auto; text-align: start; text-indent: 0px; text-transform=
: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-=
stroke-width: 0px;" class=3D""></div></blockquote><div><br class=3D""></div=
><div>The premise of <font face=3D"Courier" class=3D"">shared_ptr<T>:=
:shared_ptr(const shared_ptr<Y>& r, T* p)</font> is to pass =
a <font face=3D"Courier" class=3D"">p</font> which is owned by <font face=
=3D"Courier" class=3D"">r</font>. If the same thing were done for <font fac=
e=3D"Courier" class=3D"">value_ptr</font>, the clone of <font face=3D"Couri=
er" class=3D"">r</font> wouldn=E2=80=99t own <font face=3D"Courier" class=
=3D"">p</font>. So the equivalent would instead be<font face=3D"Courier" cl=
ass=3D""> value_ptr<T>::value_ptr(const value_ptr<Y>& r, F =
f)</font> where <font face=3D"Courier" class=3D"">F</font> is an accessor t=
aking <font face=3D"Courier" class=3D"">Y*</font> and returning <font face=
=3D"Courier" class=3D"">T*</font>. Complicated, maybe, but very general, si=
nce the various pointer conversions can be synthesized by F accessors.</div=
><div class=3D""><br class=3D""></div><blockquote type=3D"cite" class=3D"">=
<div class=3D""><blockquote type=3D"cite" style=3D"font-family: Helvetica; =
font-size: 12px; font-style: normal; font-variant: normal; font-weight: nor=
mal; letter-spacing: normal; orphans: auto; text-align: start; text-indent:=
0px; text-transform: none; white-space: normal; widows: auto; word-spacing=
: 0px; -webkit-text-stroke-width: 0px;" class=3D"">The lazy approach to val=
ue_ptr design would be to reuse shared_ptr<br class=3D"">implementation, an=
d the results should be good. Or so I think. Maybe I=E2=80=99ll<br class=3D=
"">take a shot, but there are other things I should be doing now.<br class=
=3D""></blockquote><br style=3D"font-family: Helvetica; font-size: 12px; fo=
nt-style: normal; font-variant: normal; font-weight: normal; letter-spacing=
: normal; orphans: auto; text-align: start; text-indent: 0px; text-transfor=
m: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text=
-stroke-width: 0px;" class=3D""><span style=3D"font-family: Helvetica; font=
-size: 12px; font-style: normal; font-variant: normal; font-weight: normal;=
letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px=
; text-transform: none; white-space: normal; widows: auto; word-spacing: 0p=
x; -webkit-text-stroke-width: 0px; float: none; display: inline !important;=
" class=3D"">I already have a value_ptr that is using shared_ptr internally=
to do</span><br style=3D"font-family: Helvetica; font-size: 12px; font-sty=
le: normal; font-variant: normal; font-weight: normal; letter-spacing: norm=
al; orphans: auto; text-align: start; text-indent: 0px; text-transform: non=
e; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-strok=
e-width: 0px;" class=3D""><span style=3D"font-family: Helvetica; font-size:=
12px; font-style: normal; font-variant: normal; font-weight: normal; lette=
r-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text=
-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -we=
bkit-text-stroke-width: 0px; float: none; display: inline !important;" clas=
s=3D"">type erasure.</span><br style=3D"font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant: normal; font-weight: normal; letter=
-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-=
transform: none; white-space: normal; widows: auto; word-spacing: 0px; -web=
kit-text-stroke-width: 0px;" class=3D""></div></blockquote></div><br class=
=3D""><div class=3D"">Hmm, so why not delegate <font face=3D"Courier" class=
=3D"">value_ptr::get()</font> to the encapsulated <font face=3D"Courier" cl=
ass=3D"">shared_ptr</font> and let it mediate between differing types? Gues=
s I=E2=80=99d have to take a look. There are a bunch of things going on, I=
=E2=80=99m certainly not saying it=E2=80=99s trivial=E2=80=A6</div><div cla=
ss=3D""><br class=3D""></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail=_3FC6C122-44C5-46D5-B8B6-F37656984C28--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 17:44:04 +0200
Raw View
On 10 January 2016 at 17:40, David Krauss <potswa@gmail.com> wrote:
>
> On 2016=E2=80=9301=E2=80=9310, at 11:12 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com>
> wrote:
>
> Which part of it is impossible for value_ptr?
>
>
> The premise of shared_ptr<T>::shared_ptr(const shared_ptr<Y>& r, T* p) is=
to
> pass a p which is owned by r. If the same thing were done for value_ptr, =
the
> clone of r wouldn=E2=80=99t own p. So the equivalent would instead be
> value_ptr<T>::value_ptr(const value_ptr<Y>& r, F f) where F is an accesso=
r
> taking Y* and returning T*. Complicated, maybe, but very general, since t=
he
> various pointer conversions can be synthesized by F accessors.
I haven't considered supporting that particular function, and will not
support it
unless someone explains why it's essential.
> I already have a value_ptr that is using shared_ptr internally to do
> type erasure.
>
>
> Hmm, so why not delegate value_ptr::get() to the encapsulated shared_ptr =
and
> let it mediate between differing types? Guess I=E2=80=99d have to take a =
look. There
> are a bunch of things going on, I=E2=80=99m certainly not saying it=E2=80=
=99s trivial=E2=80=A6
I already do that delegation. The "Gustafsson Dilemma" doesn't exist,
there are multiple
ways to avoid it: either do what shared_ptr does or use a covariant
return in a type-erased
implementation. The former is better.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sun, 10 Jan 2016 08:41:50 -0800 (PST)
Raw View
------=_Part_2491_971664847.1452444110210
Content-Type: multipart/alternative;
boundary="----=_Part_2492_599151188.1452444110210"
------=_Part_2492_599151188.1452444110210
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Ok, I think I have straightened all this out. as you have concluded the=20
trick that makes shared_ptr work is that in each copy=20
construction/assignment step the offset addition is done to get a pointer=
=20
valid for the new T, while the contorl block holds the original pointer it=
=20
knows how to delete.
Not so easy for a deep_ptr. What we have is a function that can clone the=
=20
original pointer and return a new pointer to the original type. But this=20
pointer may be several copy construction steps away from the T of the=20
current deep_ptr being copied. The memory of how those conversions were=20
done is long lost.
It is however, as someone mentioned, possible to preserve a chain of=20
pointer converters, but it requires heap storage (which can be small-object=
=20
optimized). I have a sample implementation which does this, attached.
I admit that my original "Gustafsson dilemma" code required downcasts but=
=20
as you astute people have concluded the problem arises even with only=20
upcasts in the face of multiple inheritance (I didn't even know of the=20
covariant return type issue with vtbls so I didn't consider that). Attached=
=20
is a test program with upcasts that breaks unless you have the caster chain=
=20
in place.
I assume that my function pointer vector can be replaced by some lambda=20
expression stored in a std::function but that's a detail, the idea is the=
=20
same.
Den s=C3=B6ndag 10 januari 2016 kl. 16:44:08 UTC+1 skrev Ville Voutilainen:
>
> On 10 January 2016 at 17:40, David Krauss <pot...@gmail.com <javascript:>=
>=20
> wrote:=20
> >=20
> > On 2016=E2=80=9301=E2=80=9310, at 11:12 PM, Ville Voutilainen <ville.vo=
....@gmail.com=20
> <javascript:>>=20
> > wrote:=20
> >=20
> > Which part of it is impossible for value_ptr?=20
> >=20
> >=20
> > The premise of shared_ptr<T>::shared_ptr(const shared_ptr<Y>& r, T* p)=
=20
> is to=20
> > pass a p which is owned by r. If the same thing were done for value_ptr=
,=20
> the=20
> > clone of r wouldn=E2=80=99t own p. So the equivalent would instead be=
=20
> > value_ptr<T>::value_ptr(const value_ptr<Y>& r, F f) where F is an=20
> accessor=20
> > taking Y* and returning T*. Complicated, maybe, but very general, since=
=20
> the=20
> > various pointer conversions can be synthesized by F accessors.=20
>
> I haven't considered supporting that particular function, and will not=20
> support it=20
> unless someone explains why it's essential.=20
>
> > I already have a value_ptr that is using shared_ptr internally to do=20
> > type erasure.=20
> >=20
> >=20
> > Hmm, so why not delegate value_ptr::get() to the encapsulated shared_pt=
r=20
> and=20
> > let it mediate between differing types? Guess I=E2=80=99d have to take =
a look.=20
> There=20
> > are a bunch of things going on, I=E2=80=99m certainly not saying it=E2=
=80=99s trivial=E2=80=A6=20
>
>
> I already do that delegation. The "Gustafsson Dilemma" doesn't exist,=20
> there are multiple=20
> ways to avoid it: either do what shared_ptr does or use a covariant=20
> return in a type-erased=20
> implementation. The former is better.=20
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_2492_599151188.1452444110210
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Ok, I think I have straightened all this out. as you have =
concluded the trick that makes shared_ptr work is that in each copy constru=
ction/assignment step the offset addition is done to get a pointer valid fo=
r the new T, while the contorl block holds the original pointer it knows ho=
w to delete.<div><br></div><div>Not so easy for a deep_ptr. What we have is=
a function that can clone the original pointer and return a new pointer to=
the original type. But this pointer may be several copy construction steps=
away from the T of the current deep_ptr being copied. The memory of how th=
ose conversions were done is long lost.</div><div><br></div><div>It is howe=
ver, as someone mentioned, possible to preserve a chain of pointer converte=
rs, but it requires heap storage (which can be small-object optimized). I h=
ave a sample implementation which does this, attached.</div><div><br></div>=
<div>I admit that my original "Gustafsson dilemma" code required =
downcasts but as you astute people have concluded the problem arises even w=
ith only upcasts in the face of multiple inheritance (I didn't even kno=
w of the covariant return type issue with vtbls so I didn't consider th=
at). Attached is a test program with upcasts that breaks unless you have th=
e caster chain in place.</div><div><br></div><div>I assume that my function=
pointer vector can be replaced by some lambda expression stored in a std::=
function but that's a detail, the idea is the same.</div><div><br></div=
><div><div><br>Den s=C3=B6ndag 10 januari 2016 kl. 16:44:08 UTC+1 skrev Vil=
le Voutilainen:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 10 January 2=
016 at 17:40, David Krauss <<a href=3D"javascript:" target=3D"_blank" gd=
f-obfuscated-mailto=3D"GRd7FBrtFAAJ" rel=3D"nofollow" onmousedown=3D"this.h=
ref=3D'javascript:';return true;" onclick=3D"this.href=3D'javas=
cript:';return true;">pot...@gmail.com</a>> wrote:
<br>>
<br>> On 2016=E2=80=9301=E2=80=9310, at 11:12 PM, Ville Voutilainen <=
<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"GRd7FBrt=
FAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';ret=
urn true;" onclick=3D"this.href=3D'javascript:';return true;">ville=
..vo...@gmail.com</a>>
<br>> wrote:
<br>>
<br>> Which part of it is impossible for value_ptr?
<br>>
<br>>
<br>> The premise of shared_ptr<T>::shared_ptr(<wbr>const shared_p=
tr<Y>& r, T* p) is to
<br>> pass a p which is owned by r. If the same thing were done for valu=
e_ptr, the
<br>> clone of r wouldn=E2=80=99t own p. So the equivalent would instead=
be
<br>> value_ptr<T>::value_ptr(const value_ptr<Y>& r, F f=
) where F is an accessor
<br>> taking Y* and returning T*. Complicated, maybe, but very general, =
since the
<br>> various pointer conversions can be synthesized by F accessors.
<br>
<br>I haven't considered supporting that particular function, and will =
not
<br>support it
<br>unless someone explains why it's essential.
<br>
<br>> I already have a value_ptr that is using shared_ptr internally to =
do
<br>> type erasure.
<br>>
<br>>
<br>> Hmm, so why not delegate value_ptr::get() to the encapsulated shar=
ed_ptr and
<br>> let it mediate between differing types? Guess I=E2=80=99d have to =
take a look. There
<br>> are a bunch of things going on, I=E2=80=99m certainly not saying i=
t=E2=80=99s trivial=E2=80=A6
<br>
<br>
<br>I already do that delegation. The "Gustafsson Dilemma" doesn&=
#39;t exist,
<br>there are multiple
<br>ways to avoid it: either do what shared_ptr does or use a covariant
<br>return in a type-erased
<br>implementation. The former is better.
<br></blockquote></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_2492_599151188.1452444110210--
------=_Part_2491_971664847.1452444110210
Content-Type: text/x-chdr; charset=US-ASCII; name=bg_deep_ptr.h
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=bg_deep_ptr.h
X-Attachment-Id: 5be2a650-3203-4d26-945a-93c754287b5e
Content-ID: <5be2a650-3203-4d26-945a-93c754287b5e>
#include <type_traits>
#include <cassert>
#include <vector>
// A pointer to one of these function pointer tables is what is carried around by the deep_ptr. This has the same runtime cost as
// inplace newing an object with virtual methods, but without the ugliness.
struct cloner_vtable {
void* (*clone)(const void* src);
void (*deallocate)(const void* src);
};
// Special table used for nullptr pointers. This allows the copy ctor and operator= to work as expected without any special ifs.
cloner_vtable null_table = {
[](const void*)->void* { return nullptr; },
[](const void*) {}
};
// Implementation of the explcit vtbl for each T.
template<typename T> struct vtable_instance {
static cloner_vtable table;
};
template<typename T> cloner_vtable vtable_instance<T>::table = {
[](const void* src)->void* { return new T(*reinterpret_cast<const T*>(src)); },
[](const void* src) { delete reinterpret_cast<const T*>(src); }
};
// Generator for caster functions that can be placed in the _casters vector of deep pointers.
template<typename T, typename U> void* caster(void* src) { return static_cast<T*>(reinterpret_cast<U*>(src)); }
// Incomplete but shows the interesting properties concisely.
template <typename T> class deep_ptr {
public:
// This is needed for the template copy ctor and assignment to be able to access the source members. I think this is
// better than having getters for them (maybe).
template <typename U> friend class deep_ptr;
deep_ptr() = default;
deep_ptr(const nullptr_t& p) : deep_ptr() {}
deep_ptr(T* org) : _data(org), org_data(org), _cloner(&vtable_instance<T>::table) {}
template<typename U> deep_ptr(U* org) : _data(static_cast<T*>(org)), org_data(org), _cloner(&cloner_vtable<U>::table) {}
// there is something that forces you to have a non-template copy ctor if I remember correctly.
deep_ptr(const deep_ptr<T>& src) : org_data(reinterpret_cast<T*>(src._cloner->clone)(src._data)), _cloner(src._cloner), _casters(src._casters) {
_data = reinterpret_cast<T*>(org_data); // No offset needed here!
// No additional caster needed either
}
template<class U> deep_ptr(const deep_ptr<U>& src) : org_data((src._cloner->clone)(src.org_data)), _cloner(src._cloner), _casters(src._casters) {
//_data = reinterpret_cast<U*>(org_data); // No offset for the moment. This makes the breaker code do the wrong thing... ?????????????????????
_casters.push_back(caster<T, U>);
void* p = org_data;
for (auto c : _casters)
p = c(p);
_data = reinterpret_cast<T*>(p);
}
~deep_ptr() {
(_cloner->deallocate)(org_data);
}
T& operator*() { return *_data; }
T* operator->() { return _data; }
// etc.
private:
T* _data = nullptr; // This is the data pointer with offset.
void* org_data = nullptr; // This is the original data pointer that the cloner works on.
cloner_vtable* _cloner = &null_table; // this pointer points to a function table for the actual subclass pointed to.
std::vector<void* (*)(void*)> _casters;
};
------=_Part_2491_971664847.1452444110210
Content-Type: text/x-c++src; charset=US-ASCII; name=deep_ptr_breaker.cpp
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=deep_ptr_breaker.cpp
X-Attachment-Id: 8006a2f2-963e-4fa0-ab0e-d15767b24fb0
Content-ID: <8006a2f2-963e-4fa0-ab0e-d15767b24fb0>
#include "bg_deep_ptr.h"
#include <iostream>
#include <memory>
using std::cout;
using std::endl;
struct Base1 {
virtual void func1() { cout << "Base1" << endl; }
};
struct Base2 {
virtual void func2() { cout << "Base2" << endl; }
};
struct Base3 {
virtual void func3() { cout << "Base3" << endl; }
};
class Sub1 : public Base1 {
};
class Sub2 : public Base2, public Sub1 {
};
class Sub3 : public Base3, public Sub2 {
};
int main()
{
// first check that it works.
cout << "By value" << endl;
Sub3 s3;
s3.func1();
s3.func2();
s3.func3();
// check that regular pointer upcasts work.
cout << "By pointer" << endl;
Sub3* s3p = new Sub3;
s3p->func1();
s3p->func2();
s3p->func3();
// check that regular upcasting to second base works.
cout << "By base pointer" << endl;
Base1* b1p = s3p;
b1p->func1();
Base2* b2p = s3p;
b2p->func2();
Base3* b3p = s3p;
b3p->func3();
// check that regular upcasting to second base in two steps works.
cout << "Call Base1 after two upcasts" << endl;
Sub2* s2p = s3p; // Offsetting beyond the Base3 vtbl
s2p->func2();
Sub1* s1p = s2p; // Further offsetting
s1p->func1();
// Try the same with shared_ptr, which in each step will clone the initial Sub3 object.
cout << "Call Base2 after two std::shared_ptr upcasts" << endl;
std::shared_ptr<Sub3> s3sp = std::make_shared<Sub3>();
std::shared_ptr<Sub2> s2sp = s3sp; // Still fine, we have T and U available
s2sp->func2();
std::shared_ptr<Sub1> s1sp = s2sp; // Not good, the U is not the real original type.
s1sp->func1(); // Calls the wrong function as the offsetting went wrong, pointing s1dp at the wrong vtbl.
// Try the same with deep_ptr, which in each step will clone the initial Sub3 object.
cout << "Call Base2 after two deep_ptr upcasts" << endl;
deep_ptr<Sub3> s3dp = new Sub3;
deep_ptr<Sub2> s2dp = s3dp; // Still fine, the cast in the T,U copy ctor does its work.
s2dp->func2();
deep_ptr<Sub1> s1dp = s2dp; // Not good, the U is not the real original type.
s1dp->func1(); // Calls the wrong function as the offsetting went wrong, pointing s1dp at the wrong vtbl.
}
------=_Part_2491_971664847.1452444110210--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 19:16:34 +0200
Raw View
--001a11439d027f89bc0528fdfb4f
Content-Type: text/plain; charset=UTF-8
On 10 January 2016 at 18:41, Bengt Gustafsson
<bengt.gustafsson@beamways.com> wrote:
> Ok, I think I have straightened all this out. as you have concluded the
> trick that makes shared_ptr work is that in each copy
> construction/assignment step the offset addition is done to get a pointer
> valid for the new T, while the contorl block holds the original pointer it
> knows how to delete.
>
> Not so easy for a deep_ptr. What we have is a function that can clone the
> original pointer and return a new pointer to the original type. But this
> pointer may be several copy construction steps away from the T of the
> current deep_ptr being copied. The memory of how those conversions were done
> is long lost.
That's not the issue. A templated conversion constructor can take the
pointer type
from the source cloner, and convert at that point.
>
> It is however, as someone mentioned, possible to preserve a chain of pointer
> converters, but it requires heap storage (which can be small-object
> optimized). I have a sample implementation which does this, attached.
I use a chain of converters because I need to *hold* the different cloners, not
because there would be an issue with invoking them when converting.
The allocation problem is real, though. A cloner can clone the value,
clone itself,
destroy the value (and destroy the cloner itself, although my
prototype doesn't do
that bit yet) fine, but allocating the delegate is a different matter.
I'll attach the current version I have. It's very much a work-in-progress.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11439d027f89bc0528fdfb4f
Content-Type: text/x-c++src; charset=US-ASCII; name="cloned_ptr.cpp"
Content-Disposition: attachment; filename="cloned_ptr.cpp"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_ij8swnxz2
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4K
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGUgPGNsYXNzIFQ+CnN0cnVjdCBjbG9uZXJf
aW1wbCB7CiAgdHlwZWRlZiBUKiBwb2ludGVyOwogIHZpcnR1YWwgVCogY2xvbmUoVCopID0gMDsK
ICB2aXJ0dWFsIGNsb25lcl9pbXBsPFQ+KiBjbG9uZSgpID0gMDsKICB2aXJ0dWFsIHZvaWQgZGVz
dHJveShUKikgPSAwOwogIHZpcnR1YWwgfmNsb25lcl9pbXBsKCkge30KfTsKCnRlbXBsYXRlIDxj
bGFzcyBUPgpzdHJ1Y3QgY2xvbmVyCnsKICB0eXBlZGVmIFQqIHBvaW50ZXI7CiAgVCogY2xvbmUo
VCogdnNvdXJjZSkKICB7CiAgICBpZiAodnNvdXJjZSkKICAgICAgcmV0dXJuIG5ldyBUKCp2c291
cmNlKTsKICAgIHJldHVybiBudWxscHRyOwogIH0KICB2b2lkIGRlc3Ryb3koVCogdnNvdXJjZSkK
ICB7CiAgICBkZWxldGUgdnNvdXJjZTsKICB9CiAgY2xvbmVyKiBjbG9uZSgpCiAgewogICAgcmV0
dXJuIG5ldyBjbG9uZXIoKnRoaXMpOwogIH0KICB+Y2xvbmVyKCkge30KfTsKCnRlbXBsYXRlIDxj
bGFzcyBUPiBzdHJ1Y3QgY2xvbmVyX2RlbGV0ZXIKewogIGNsb25lcl9pbXBsPFQ+KiBpbXBsOwog
IGNsb25lcl9kZWxldGVyKGNsb25lcl9pbXBsPFQ+KiBpbXBsKSA6IGltcGwoaW1wbCkge30KICB2
b2lkIG9wZXJhdG9yKCkoVCogdCkKICB7CiAgICBpbXBsLT5kZXN0cm95KHQpOwogIH0KfTsKCnRl
bXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPgpzdHJ1Y3QgZGVsZWdhdGluZ19jbG9uZXIgOiBjbG9u
ZXJfaW1wbDxUPgp7CiAgVSBpbXBsOwogIGRlbGVnYXRpbmdfY2xvbmVyKFUgdSkgOiBpbXBsKHUp
IHt9CiAgdmlydHVhbCBUKiBjbG9uZShUKiB2c291cmNlKQogIHsKICAgIHJldHVybiBpbXBsLT5j
bG9uZShzdGF0aWNfY2FzdDx0eXBlbmFtZSBVOjplbGVtZW50X3R5cGU6OnBvaW50ZXI+KHZzb3Vy
Y2UpKTsKICB9CiAgdm9pZCBkZXN0cm95KFQqIHZzb3VyY2UpCiAgewogICAgaW1wbC0+ZGVzdHJv
eShzdGF0aWNfY2FzdDx0eXBlbmFtZSBVOjplbGVtZW50X3R5cGU6OnBvaW50ZXI+KHZzb3VyY2Up
KTsKICB9CiAgY2xvbmVyX2ltcGw8VD4qIGNsb25lKCkKICB7CiAgICB1c2luZyBlbHR5cGUgPSB0
eXBlbmFtZSBzdGQ6OnJlbW92ZV9wb2ludGVyPGRlY2x0eXBlKGltcGwtPmNsb25lKCkpPjo6dHlw
ZTsKICAgIHJldHVybiBuZXcgZGVsZWdhdGluZ19jbG9uZXIoc3RkOjpzaGFyZWRfcHRyPGVsdHlw
ZT4oaW1wbC0+Y2xvbmUoKSkpOwogIH0KICB+ZGVsZWdhdGluZ19jbG9uZXIoKSB7fQp9OwoKCnRl
bXBsYXRlIDxjbGFzcyBUPgpzdHJ1Y3QgY2xvbmVkX3B0cgp7CiAgbXV0YWJsZSBzdGQ6OnNoYXJl
ZF9wdHI8Y2xvbmVyX2ltcGw8VD4+IGNsb25lcl87CiAgc3RkOjpzaGFyZWRfcHRyPFQ+IHZhbDsK
ICBjbG9uZWRfcHRyKFQqIHNyYykgOiAKICAgIGNsb25lcl97c3RkOjptYWtlX3NoYXJlZDxkZWxl
Z2F0aW5nX2Nsb25lcjxULCBzdGQ6OnNoYXJlZF9wdHI8Y2xvbmVyPFQ+Pj4+KHN0ZDo6bWFrZV9z
aGFyZWQ8Y2xvbmVyPFQ+PihjbG9uZXI8VD57fSkpfSwKICAgIHZhbHtzcmMsIGNsb25lcl9kZWxl
dGVyPFQ+KGNsb25lcl8uZ2V0KCkpfQogIHt9CiAgdGVtcGxhdGUgPGNsYXNzIFU+CiAgY2xvbmVk
X3B0cihUKiBzcmMsIFUgc2Nsb25lcikgOiAKICAgIGNsb25lcl97c3RkOjptYWtlX3NoYXJlZDxk
ZWxlZ2F0aW5nX2Nsb25lcjxULCBzdGQ6OnNoYXJlZF9wdHI8VT4+PihzdGQ6Om1ha2Vfc2hhcmVk
PFU+KHNjbG9uZXIpKX0sCiAgICB2YWx7c3JjLCBjbG9uZXJfZGVsZXRlcjxUPihjbG9uZXJfLmdl
dCgpKX0KICB7fQoKICAvLyAgY2xvbmVkX3B0cihjb25zdCB2b2xhdGlsZSBjbG9uZWRfcHRyJiBv
dGhlcikgPSBkZWxldGU7CiAgY2xvbmVkX3B0cihjb25zdCBjbG9uZWRfcHRyJiBvdGhlcikKICB7
CiAgICBjbG9uZXJfLnJlc2V0KG90aGVyLmNsb25lcl8tPmNsb25lKCkpOwogICAgdmFsLnJlc2V0
KG90aGVyLmNsb25lcl8tPmNsb25lKG90aGVyLnZhbC5nZXQoKSksIGNsb25lcl9kZWxldGVyPFQ+
KGNsb25lcl8uZ2V0KCkpKTsKICB9CiAgdGVtcGxhdGUgPGNsYXNzIFU+CiAgY2xvbmVkX3B0cihj
b25zdCBjbG9uZWRfcHRyPFU+JiBvdGhlcikKICB7CgogICAgYXV0byogb3RoZXJfY2xvbmVyID0g
b3RoZXIuY2xvbmVyXy0+Y2xvbmUoKTsKICAgIHVzaW5nIGVsdHlwZSA9IHR5cGVuYW1lIHN0ZDo6
cmVtb3ZlX3JlZmVyZW5jZTxkZWNsdHlwZSgqb3RoZXJfY2xvbmVyKT46OnR5cGU7CiAgICBjbG9u
ZXJfID0gc3RkOjptYWtlX3NoYXJlZDwKICAgICAgZGVsZWdhdGluZ19jbG9uZXI8VCwgc3RkOjpz
aGFyZWRfcHRyPGVsdHlwZT4+PgogICAgICAoc3RkOjpzaGFyZWRfcHRyPGVsdHlwZT4ob3RoZXJf
Y2xvbmVyKSk7CiAgICB2YWwucmVzZXQob3RoZXIuY2xvbmVyXy0+Y2xvbmUob3RoZXIudmFsLmdl
dCgpKSwgY2xvbmVyX2RlbGV0ZXI8VD4oY2xvbmVyXy5nZXQoKSkpOwogIH0KICBjbG9uZWRfcHRy
KGNsb25lZF9wdHImJiBvdGhlcikKICB7CiAgICB2YWwgPSBzdGQ6Om1vdmUob3RoZXIudmFsKTsK
ICAgIGNsb25lcl8gPSBzdGQ6Om1vdmUob3RoZXIuY2xvbmVyXyk7CiAgfQogIHRlbXBsYXRlIDxj
bGFzcyBVPgogIGNsb25lZF9wdHIoY2xvbmVkX3B0cjxVPiYmIG90aGVyKQogIHsKICAgIHZhbCA9
IHN0ZDo6bW92ZShvdGhlci52YWwpOwogICAgYXV0byBvdGhlcl9jbG9uZXIgPSBzdGQ6Om1vdmUo
b3RoZXIuY2xvbmVyXyk7CiAgICB1c2luZyBlbHR5cGUgPSB0eXBlbmFtZSBzdGQ6OnJlbW92ZV9y
ZWZlcmVuY2U8ZGVjbHR5cGUoKm90aGVyX2Nsb25lcik+Ojp0eXBlOwogICAgY2xvbmVyXyA9IHN0
ZDo6bWFrZV9zaGFyZWQ8CiAgICAgIGRlbGVnYXRpbmdfY2xvbmVyPFQsIHN0ZDo6c2hhcmVkX3B0
cjxlbHR5cGU+Pj4ob3RoZXJfY2xvbmVyKTsKCiAgfQogIGNsb25lZF9wdHImIG9wZXJhdG9yPShj
b25zdCBjbG9uZWRfcHRyJiBvdGhlcikKICB7CiAgICBjbG9uZWRfcHRyIHRtcChvdGhlcik7CiAg
ICBzdGQ6OnN3YXAodmFsLCB0bXAudmFsKTsKICAgIHN0ZDo6c3dhcChjbG9uZXJfLCB0bXAuY2xv
bmVyXyk7CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIHRlbXBsYXRlIDxjbGFzcyBVPgogIGNsb25l
ZF9wdHImIG9wZXJhdG9yPShjb25zdCBjbG9uZWRfcHRyPFU+JiBvdGhlcikKICB7CiAgICBjbG9u
ZWRfcHRyIHRtcChvdGhlcik7CiAgICBzdGQ6OnN3YXAodmFsLCB0bXAudmFsKTsKICAgIHN0ZDo6
c3dhcChjbG9uZXJfLCB0bXAuY2xvbmVyXyk7CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIGNsb25l
ZF9wdHImIG9wZXJhdG9yPShjb25zdCBjbG9uZWRfcHRyJiYgb3RoZXIpCiAgewogICAgY2xvbmVk
X3B0ciB0bXAoc3RkOjptb3ZlKG90aGVyKSk7CiAgICBzdGQ6OnN3YXAodmFsLCB0bXAudmFsKTsK
ICAgIHN0ZDo6c3dhcChjbG9uZXJfLCB0bXAuY2xvbmVyXyk7CiAgICByZXR1cm4gKnRoaXM7CiAg
fQogIHRlbXBsYXRlIDxjbGFzcyBVPgogIGNsb25lZF9wdHImIG9wZXJhdG9yPShjb25zdCBjbG9u
ZWRfcHRyPFU+JiYgb3RoZXIpCiAgewogICAgY2xvbmVkX3B0ciB0bXAoc3RkOjptb3ZlKG90aGVy
KSk7CiAgICBzdGQ6OnN3YXAodmFsLCB0bXAudmFsKTsKICAgIHN0ZDo6c3dhcChjbG9uZXJfLCB0
bXAuY2xvbmVyXyk7CiAgICByZXR1cm4gKnRoaXM7CiAgfQogIGF1dG8gb3BlcmF0b3ItPigpIHty
ZXR1cm4gdmFsLm9wZXJhdG9yLT4oKTt9CiAgYXV0byBnZXQoKSB7cmV0dXJuIHZhbC5nZXQoKTt9
Cn07Cgp0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgQWxsb2M9c3RkOjphbGxvY2F0b3I8VD4+CnN0
cnVjdCBhbm90aGVyX2Nsb25lcgp7CiAgdHlwZWRlZiBUKiBwb2ludGVyOwogIEFsbG9jIGE7CiAg
YW5vdGhlcl9jbG9uZXIoKSA9IGRlZmF1bHQ7CiAgYW5vdGhlcl9jbG9uZXIoQWxsb2MgYSkgOiBh
KGEpIHt9CiAgVCogY2xvbmUoVCogdnNvdXJjZSkKICB7CiAgICBzdGQ6OmNvdXQgPDwgImFub3Ro
ZXJfY2xvbmVyIiA8PCBzdGQ6OmVuZGw7CiAgICBUKiB0bXAgPSBudWxscHRyOwogICAgaWYgKHZz
b3VyY2UpIHsKICAgICAgdG1wID0gc3RkOjphbGxvY2F0b3JfdHJhaXRzPHN0ZDo6YWxsb2NhdG9y
PFQ+Pjo6YWxsb2NhdGUoYSwgc2l6ZW9mKFQpKTsKICAgICAgc3RkOjphbGxvY2F0b3JfdHJhaXRz
PHN0ZDo6YWxsb2NhdG9yPFQ+Pjo6Y29uc3RydWN0KGEsIHRtcCwgKnZzb3VyY2UpOwogICAgfQog
ICAgcmV0dXJuIHRtcDsKICB9CiAgdm9pZCBkZXN0cm95KFQqIHYpCiAgewogICAgc3RkOjphbGxv
Y2F0b3JfdHJhaXRzPHN0ZDo6YWxsb2NhdG9yPFQ+Pjo6ZGVzdHJveShhLCAoVCopdik7CiAgICBz
dGQ6OmFsbG9jYXRvcl90cmFpdHM8c3RkOjphbGxvY2F0b3I8VD4+OjpkZWFsbG9jYXRlKGEsIChU
Kil2LCBzaXplb2YoVCkpOwogIH0KICBhbm90aGVyX2Nsb25lciogY2xvbmUoKQogIHsKICAgIHJl
dHVybiBuZXcgYW5vdGhlcl9jbG9uZXIoKnRoaXMpOwogIH0KICB+YW5vdGhlcl9jbG9uZXIoKSB7
fQp9OwoKCnN0cnVjdCBCIHt2aXJ0dWFsIH5CKCkge3N0ZDo6Y291dCA8PCAifkIoKSIgPDwgc3Rk
OjplbmRsO319OwpzdHJ1Y3QgRCA6IEIge35EKCkge3N0ZDo6Y291dCA8PCAifkQoKSIgPDwgc3Rk
OjplbmRsO319OwpzdHJ1Y3QgRDIgOiBCIHt+RDIoKSB7c3RkOjpjb3V0IDw8ICJ+RDIoKSIgPDwg
c3RkOjplbmRsO319OwoKY2xvbmVkX3B0cjxEPiBtYWtlX21lX2FfZCgpCnsKICByZXR1cm4gY2xv
bmVkX3B0cjxEPntuZXcgRHt9fTsKfQoKY2xvbmVkX3B0cjxEMj4gbWFrZV9tZV9hX2QyKCkKewog
IHJldHVybiBjbG9uZWRfcHRyPEQyPntuZXcgRDJ7fX07Cn0KCnZvaWQgZ2ltbWVfYmVlcyhjbG9u
ZWRfcHRyPEI+LCBjbG9uZWRfcHRyPEI+KQp7Cn0KCnN0cnVjdCBCYXNlQSB7IGludCBhXyA9IDA7
IHZpcnR1YWwgfkJhc2VBKCkgPSBkZWZhdWx0OyB2aXJ0dWFsIGludCB2YWx1ZSgpIHtyZXR1cm4g
LTE7fX07CnN0cnVjdCBCYXNlQiB7IGludCBiXyA9IDQyOyB2aXJ0dWFsIH5CYXNlQigpID0gZGVm
YXVsdDsgdmlydHVhbCBpbnQgdmFsdWUoKSB7cmV0dXJuIC0yO319OwpzdHJ1Y3QgSW50ZXJtZWRp
YXRlQmFzZUEgOiBCYXNlQSB7IGludCBpYV8gPSAzOyB2aXJ0dWFsIGludCB2YWx1ZSgpIHtyZXR1
cm4gLTM7fX07CnN0cnVjdCBJbnRlcm1lZGlhdGVCYXNlQiA6IEJhc2VCIHsgaW50IGliXyA9IDEw
MTsgdmlydHVhbCBpbnQgdmFsdWUoKSB7cmV0dXJuIC00O319OwpzdHJ1Y3QgTXVsdGlwbHlEZXJp
dmVkIDogSW50ZXJtZWRpYXRlQmFzZUEsIEludGVybWVkaWF0ZUJhc2VCIHsgaW50IHZhbHVlXyA9
IDA7IE11bHRpcGx5RGVyaXZlZChpbnQgdmFsdWUpIDogdmFsdWVfKHZhbHVlKSB7fTsgaW50IHZh
bHVlKCkge3JldHVybiB2YWx1ZV87fX07CgppbnQgbWFpbigpCnsKICBjbG9uZWRfcHRyPEI+IHgg
PSBtYWtlX21lX2FfZCgpOwogIGNsb25lZF9wdHI8Qj4geSA9IG1ha2VfbWVfYV9kMigpOwogIGNs
b25lZF9wdHI8Qj4geDIgPSB4OwogIGdpbW1lX2JlZXMoeCwgeSk7CiAgY2xvbmVkX3B0cjxEPiB6
e25ldyBEe30sIGFub3RoZXJfY2xvbmVyPEQ+e319OwogIGNsb25lZF9wdHI8Qj4genp7en07CiAg
Y2xvbmVkX3B0cjxCPiB6enp7enp9OwogIGNsb25lZF9wdHI8Qj4genp6entzdGQ6Om1vdmUoenp6
KX07CiAgenogPSB5OwogIHp6ID0gejsKICB6eiA9IHN0ZDo6bW92ZSh6KTsKICBpbnQgZGVyaXZl
ZF90eXBlX3ZhbHVlID0gNzsKICBjbG9uZWRfcHRyPE11bHRpcGx5RGVyaXZlZD4gdm1ke25ldyBN
dWx0aXBseURlcml2ZWQoZGVyaXZlZF90eXBlX3ZhbHVlKX07CiAgY2xvbmVkX3B0cjxJbnRlcm1l
ZGlhdGVCYXNlQT4gaWJhID0gdm1kOwogIHN0ZDo6Y291dCA8PCAiaWJhLT5pYV8gPT0gIiA8PCBp
YmEtPmlhXyA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICJpYmEtPmFfID09ICIgPDwgaWJh
LT5hXyA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICJpYmEtPnZhbHVlKCkgPT0gIiA8PCBp
YmEtPnZhbHVlKCkgPDwgc3RkOjplbmRsOwogIGNsb25lZF9wdHI8SW50ZXJtZWRpYXRlQmFzZUI+
IGliYiA9IHZtZDsKICBzdGQ6OmNvdXQgPDwgImliYi0+aWJfID09ICIgPDwgaWJiLT5pYl8gPDwg
c3RkOjplbmRsOwogIHN0ZDo6Y291dCA8PCAiaWJiLT5iXyA9PSAiIDw8IGliYi0+Yl8gPDwgc3Rk
OjplbmRsOwogIHN0ZDo6Y291dCA8PCAiaWJiLT52YWx1ZSgpID09ICIgPDwgaWJiLT52YWx1ZSgp
IDw8IHN0ZDo6ZW5kbDsKICBjbG9uZWRfcHRyPEJhc2VBPiBiYSA9IHZtZDsKICBzdGQ6OmNvdXQg
PDwgImJhLT5hXyA9PSAiIDw8IGJhLT5hXyA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICJi
YS0+dmFsdWUoKSA9PSAiIDw8IGJhLT52YWx1ZSgpIDw8IHN0ZDo6ZW5kbDsKICBjbG9uZWRfcHRy
PEJhc2VCPiBiYiA9IHZtZDsKICBzdGQ6OmNvdXQgPDwgImJiLT5iXyA9PSAiIDw8IGJiLT5iXyA8
PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICJiYi0+dmFsdWUoKSA9PSAiIDw8IGJiLT52YWx1
ZSgpIDw8IHN0ZDo6ZW5kbDsKICBjbG9uZWRfcHRyPEJhc2VBPiBiYTIgPSBpYmE7CiAgc3RkOjpj
b3V0IDw8ICJiYTItPmFfID09ICIgPDwgYmEyLT5hXyA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0
IDw8ICJiYTItPnZhbHVlKCkgPT0gIiA8PCBiYTItPnZhbHVlKCkgPDwgc3RkOjplbmRsOwogIGNs
b25lZF9wdHI8QmFzZUI+IGJiMiA9IGliYjsKICBzdGQ6OmNvdXQgPDwgImJiMi0+Yl8gPT0gIiA8
PCBiYjItPmJfIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmNvdXQgPDwgImJiMi0+dmFsdWUoKSA9PSAi
IDw8IGJiMi0+dmFsdWUoKSA8PCBzdGQ6OmVuZGw7CiAgY2xvbmVkX3B0cjx2b2lkPiB2cCA9IGJi
MjsKfQo=
--001a11439d027f89bc0528fdfb4f--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 19:18:43 +0200
Raw View
On 10 January 2016 at 19:16, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> I use a chain of converters because I need to *hold* the different cloners, not
> because there would be an issue with invoking them when converting.
And also, the converter is needed to adapt the original cloner to the
new one, sure.
That takes care of multiple conversions, the original type is forever
retained. One-step
conversions would work otherwise, too, but multi-step needs the adaptation, and
the specific-type in the target also needs the adaptation so that the
cloner can be
stored in the target.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sun, 10 Jan 2016 17:18:48 +0000
Raw View
--001a11454ffa76d0600528fe031d
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
I have updated my implementation. As Ville said, the failing Gustafsson's
dilemma test was a facet of my poor implementation.
Tests now pass.
My implementation propagates constness. This is not necessary but to my
mind makes sense as a deep_ptr is intended to extend the logical state of a
object. What do others think?
I have made the pointer constructor public and explicit - we should be
consistent with shared_ptr.
Implementation is here: https://github.com/jbcoe/deep_ptr
On 10 January 2016 at 16:41, Bengt Gustafsson <bengt.gustafsson@beamways.co=
m
> wrote:
> Ok, I think I have straightened all this out. as you have concluded the
> trick that makes shared_ptr work is that in each copy
> construction/assignment step the offset addition is done to get a pointer
> valid for the new T, while the contorl block holds the original pointer i=
t
> knows how to delete.
>
> Not so easy for a deep_ptr. What we have is a function that can clone the
> original pointer and return a new pointer to the original type. But this
> pointer may be several copy construction steps away from the T of the
> current deep_ptr being copied. The memory of how those conversions were
> done is long lost.
>
> It is however, as someone mentioned, possible to preserve a chain of
> pointer converters, but it requires heap storage (which can be small-obje=
ct
> optimized). I have a sample implementation which does this, attached.
>
> I admit that my original "Gustafsson dilemma" code required downcasts but
> as you astute people have concluded the problem arises even with only
> upcasts in the face of multiple inheritance (I didn't even know of the
> covariant return type issue with vtbls so I didn't consider that). Attach=
ed
> is a test program with upcasts that breaks unless you have the caster cha=
in
> in place.
>
> I assume that my function pointer vector can be replaced by some lambda
> expression stored in a std::function but that's a detail, the idea is the
> same.
>
>
> Den s=C3=B6ndag 10 januari 2016 kl. 16:44:08 UTC+1 skrev Ville Voutilaine=
n:
>>
>> On 10 January 2016 at 17:40, David Krauss <pot...@gmail.com> wrote:
>> >
>> > On 2016=E2=80=9301=E2=80=9310, at 11:12 PM, Ville Voutilainen <ville.v=
o...@gmail.com>
>> > wrote:
>> >
>> > Which part of it is impossible for value_ptr?
>> >
>> >
>> > The premise of shared_ptr<T>::shared_ptr(const shared_ptr<Y>& r, T* p)
>> is to
>> > pass a p which is owned by r. If the same thing were done for
>> value_ptr, the
>> > clone of r wouldn=E2=80=99t own p. So the equivalent would instead be
>> > value_ptr<T>::value_ptr(const value_ptr<Y>& r, F f) where F is an
>> accessor
>> > taking Y* and returning T*. Complicated, maybe, but very general, sinc=
e
>> the
>> > various pointer conversions can be synthesized by F accessors.
>>
>> I haven't considered supporting that particular function, and will not
>> support it
>> unless someone explains why it's essential.
>>
>> > I already have a value_ptr that is using shared_ptr internally to do
>> > type erasure.
>> >
>> >
>> > Hmm, so why not delegate value_ptr::get() to the encapsulated
>> shared_ptr and
>> > let it mediate between differing types? Guess I=E2=80=99d have to take=
a look.
>> There
>> > are a bunch of things going on, I=E2=80=99m certainly not saying it=E2=
=80=99s trivial=E2=80=A6
>>
>>
>> I already do that delegation. The "Gustafsson Dilemma" doesn't exist,
>> there are multiple
>> ways to avoid it: either do what shared_ptr does or use a covariant
>> return in a type-erased
>> implementation. The former is better.
>>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--001a11454ffa76d0600528fe031d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I have updated my implementation. As Ville said, the faili=
ng Gustafsson's dilemma test was a facet of my poor implementation.<div=
>Tests now pass.</div><div><br></div><div>My implementation propagates cons=
tness. This is not necessary but to my mind makes sense as a deep_ptr is in=
tended to extend the logical state of a object. What do others think?</div>=
<div><br></div><div>I have made the pointer constructor public and explicit=
- we should be consistent with shared_ptr.</div><div><br></div><div>Implem=
entation is here:=C2=A0<a href=3D"https://github.com/jbcoe/deep_ptr">https:=
//github.com/jbcoe/deep_ptr</a></div><div><br><div class=3D"gmail_extra">On=
10 January 2016 at 16:41, Bengt Gustafsson <span dir=3D"ltr"><<a href=
=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustafsso=
n@beamways.com</a>></span> wrote:<br><div class=3D"gmail_quote"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-l=
eft:1ex"><div dir=3D"ltr">Ok, I think I have straightened all this out. as =
you have concluded the trick that makes shared_ptr work is that in each cop=
y construction/assignment step the offset addition is done to get a pointer=
valid for the new T, while the contorl block holds the original pointer it=
knows how to delete.<div><br></div><div>Not so easy for a deep_ptr. What w=
e have is a function that can clone the original pointer and return a new p=
ointer to the original type. But this pointer may be several copy construct=
ion steps away from the T of the current deep_ptr being copied. The memory =
of how those conversions were done is long lost.</div><div><br></div><div>I=
t is however, as someone mentioned, possible to preserve a chain of pointer=
converters, but it requires heap storage (which can be small-object optimi=
zed). I have a sample implementation which does this, attached.</div><div><=
br></div><div>I admit that my original "Gustafsson dilemma" code =
required downcasts but as you astute people have concluded the problem aris=
es even with only upcasts in the face of multiple inheritance (I didn't=
even know of the covariant return type issue with vtbls so I didn't co=
nsider that). Attached is a test program with upcasts that breaks unless yo=
u have the caster chain in place.</div><div><br></div><div>I assume that my=
function pointer vector can be replaced by some lambda expression stored i=
n a std::function but that's a detail, the idea is the same.</div><div>=
<br></div><div><div><br>Den s=C3=B6ndag 10 januari 2016 kl. 16:44:08 UTC+1 =
skrev Ville Voutilainen:<blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);b=
order-left-style:solid;padding-left:1ex">On 10 January 2016 at 17:40, David=
Krauss <<a rel=3D"nofollow">pot...@gmail.com</a>> wrote:
<br>>
<br>> On 2016=E2=80=9301=E2=80=9310, at 11:12 PM, Ville Voutilainen <=
<a rel=3D"nofollow">ville.vo...@gmail.com</a>>
<br><div><div class=3D"h5">> wrote:
<br>>
<br>> Which part of it is impossible for value_ptr?
<br>>
<br>>
<br>> The premise of shared_ptr<T>::shared_ptr(const shared_ptr<=
;Y>& r, T* p) is to
<br>> pass a p which is owned by r. If the same thing were done for valu=
e_ptr, the
<br>> clone of r wouldn=E2=80=99t own p. So the equivalent would instead=
be
<br>> value_ptr<T>::value_ptr(const value_ptr<Y>& r, F f=
) where F is an accessor
<br>> taking Y* and returning T*. Complicated, maybe, but very general, =
since the
<br>> various pointer conversions can be synthesized by F accessors.
<br>
<br>I haven't considered supporting that particular function, and will =
not
<br>support it
<br>unless someone explains why it's essential.
<br>
<br>> I already have a value_ptr that is using shared_ptr internally to =
do
<br>> type erasure.
<br>>
<br>>
<br>> Hmm, so why not delegate value_ptr::get() to the encapsulated shar=
ed_ptr and
<br>> let it mediate between differing types? Guess I=E2=80=99d have to =
take a look. There
<br>> are a bunch of things going on, I=E2=80=99m certainly not saying i=
t=E2=80=99s trivial=E2=80=A6
<br>
<br>
<br>I already do that delegation. The "Gustafsson Dilemma" doesn&=
#39;t exist,
<br>there are multiple
<br>ways to avoid it: either do what shared_ptr does or use a covariant
<br>return in a type-erased
<br>implementation. The former is better.
<br></div></div></blockquote></div></div></div><div class=3D""><div class=
=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a11454ffa76d0600528fe031d--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 19:22:14 +0200
Raw View
On 10 January 2016 at 19:18, Jonathan Coe <jbcoe@me.com> wrote:
> I have updated my implementation. As Ville said, the failing Gustafsson's
> dilemma test was a facet of my poor implementation.
> Tests now pass.
Looks promising.
> My implementation propagates constness. This is not necessary but to my mind
> makes sense as a deep_ptr is intended to extend the logical state of a
> object. What do others think?
I am gravitating towards not propagating const in this type, since
other smart pointers
don't do that, and propagate_const can be applied on top.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Sun, 10 Jan 2016 09:32:15 -0800
Raw View
On Sunday 10 January 2016 17:44:04 Ville Voutilainen wrote:
> I already do that delegation. The "Gustafsson Dilemma" doesn't exist,
> there are multiple
> ways to avoid it: either do what shared_ptr does or use a covariant
> return in a type-erased
> implementation. The former is better.
Covariant returns will not work if the relationship between the two pointer
types crosses a virtual base or is not visible.
Example:
struct A { };
struct B { }
struct C: A, virtual B {};
shared_ptr<A> p1 = make_shared<C>();
shared_ptr<C> p2 = static_pointer_cast<C>(p1);
shared_ptr<B> p3 = static_pointer_cast<B>(p2);
There's no visible relationship between classes A and B, so shared_ptr<B>
cannot possibly store a pointer to A. If it stored a pointer to C, it would
require a dynamic_cast to cast from C to B.
The only reasonable answer is that a shared_ptr<B> has a pointer to B.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 19:36:41 +0200
Raw View
On 10 January 2016 at 19:32, Thiago Macieira <thiago@macieira.org> wrote:
> On Sunday 10 January 2016 17:44:04 Ville Voutilainen wrote:
>> I already do that delegation. The "Gustafsson Dilemma" doesn't exist,
>> there are multiple
>> ways to avoid it: either do what shared_ptr does or use a covariant
>> return in a type-erased
>> implementation. The former is better.
>
> Covariant returns will not work if the relationship between the two pointer
> types crosses a virtual base or is not visible.
>
> Example:
>
> struct A { };
> struct B { }
> struct C: A, virtual B {};
>
> shared_ptr<A> p1 = make_shared<C>();
> shared_ptr<C> p2 = static_pointer_cast<C>(p1);
> shared_ptr<B> p3 = static_pointer_cast<B>(p2);
>
> There's no visible relationship between classes A and B, so shared_ptr<B>
> cannot possibly store a pointer to A. If it stored a pointer to C, it would
> require a dynamic_cast to cast from C to B.
I don't see anything alarming in any of that.
> The only reasonable answer is that a shared_ptr<B> has a pointer to B.
Well, it certainly looks like converting in a converting constructor
is in many ways
superior to using a covariant return type.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sun, 10 Jan 2016 17:39:01 +0000
Raw View
--047d7b6d9fb6c3645e0528fe4b58
Content-Type: text/plain; charset=UTF-8
On 10 January 2016 at 17:22, Ville Voutilainen <ville.voutilainen@gmail.com>
wrote:
> On 10 January 2016 at 19:18, Jonathan Coe <jbcoe@me.com> wrote:
> > I have updated my implementation. As Ville said, the failing Gustafsson's
> > dilemma test was a facet of my poor implementation.
> > Tests now pass.
>
> Looks promising.
>
> > My implementation propagates constness. This is not necessary but to my
> mind
> > makes sense as a deep_ptr is intended to extend the logical state of a
> > object. What do others think?
>
> I am gravitating towards not propagating const in this type, since
> other smart pointers
> don't do that, and propagate_const can be applied on top.
>
>
Agreed.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b6d9fb6c3645e0528fe4b58
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 10 January 2016 at 17:22, Ville Voutilainen <span dir=
=3D"ltr"><<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blan=
k">ville.voutilainen@gmail.com</a>></span> wrote:<br><div class=3D"gmail=
_extra"><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"><span cl=
ass=3D"">On 10 January 2016 at 19:18, Jonathan Coe <<a href=3D"mailto:jb=
coe@me.com">jbcoe@me.com</a>> wrote:<br>
> I have updated my implementation. As Ville said, the failing Gustafsso=
n's<br>
> dilemma test was a facet of my poor implementation.<br>
> Tests now pass.<br>
<br>
</span>Looks promising.<br>
<span class=3D""><br>
> My implementation propagates constness. This is not necessary but to m=
y mind<br>
> makes sense as a deep_ptr is intended to extend the logical state of a=
<br>
> object. What do others think?<br>
<br>
</span>I am gravitating towards not propagating const in this type, since<b=
r>
other smart pointers<br>
don't do that, and propagate_const can be applied on top.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br></div></div></blockquote><div><=
br></div><div>Agreed.</div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div class=3D"HOEnZb"><div class=3D"h5">
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7b6d9fb6c3645e0528fe4b58--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 10 Jan 2016 19:43:48 +0200
Raw View
On 10 January 2016 at 19:39, Jonathan Coe <jbcoe@me.com> wrote:
>> > My implementation propagates constness. This is not necessary but to my
>> > mind
>> > makes sense as a deep_ptr is intended to extend the logical state of a
>> > object. What do others think?
>>
>> I am gravitating towards not propagating const in this type, since
>> other smart pointers
>> don't do that, and propagate_const can be applied on top.
> Agreed.
Another thing: const propagation is easy to slap on top with propagate_const,
but if the type does it built-in and the user for whatever reason
doesn't want it,
bypassing the const propagation is.. ..interesting, to say the least, right?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sun, 10 Jan 2016 18:09:17 +0000
Raw View
--047d7b111e770305160528feb8c7
Content-Type: text/plain; charset=UTF-8
On 10 January 2016 at 17:43, Ville Voutilainen <ville.voutilainen@gmail.com>
wrote:
> On 10 January 2016 at 19:39, Jonathan Coe <jbcoe@me.com> wrote:
> >> > My implementation propagates constness. This is not necessary but to
> my
> >> > mind
> >> > makes sense as a deep_ptr is intended to extend the logical state of a
> >> > object. What do others think?
> >>
> >> I am gravitating towards not propagating const in this type, since
> >> other smart pointers
> >> don't do that, and propagate_const can be applied on top.
> > Agreed.
>
>
> Another thing: const propagation is easy to slap on top with
> propagate_const,
> but if the type does it built-in and the user for whatever reason
> doesn't want it,
> bypassing the const propagation is.. ..interesting, to say the least,
> right?
>
Agreed.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b111e770305160528feb8c7
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra">On 10 January 2016 at 17:43=
, Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto:ville.voutilain=
en@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com</a>></span> =
wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span c=
lass=3D"">On 10 January 2016 at 19:39, Jonathan Coe <<a href=3D"mailto:j=
bcoe@me.com">jbcoe@me.com</a>> wrote:<br>
>> > My implementation propagates constness. This is not necessary=
but to my<br>
>> > mind<br>
>> > makes sense as a deep_ptr is intended to extend the logical s=
tate of a<br>
>> > object. What do others think?<br>
>><br>
>> I am gravitating towards not propagating const in this type, since=
<br>
>> other smart pointers<br>
>> don't do that, and propagate_const can be applied on top.<br>
> Agreed.<br>
<br>
<br>
</span>Another thing: const propagation is easy to slap on top with propaga=
te_const,<br>
but if the type does it built-in and the user for whatever reason<br>
doesn't want it,<br>
bypassing the const propagation is.. ..interesting, to say the least, right=
?<br></blockquote><div><br></div><div>Agreed.</div><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex">
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7b111e770305160528feb8c7--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 12 Jan 2016 04:27:13 -0800 (PST)
Raw View
------=_Part_4837_723397248.1452601633554
Content-Type: multipart/alternative;
boundary="----=_Part_4838_1731395046.1452601633555"
------=_Part_4838_1731395046.1452601633555
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Ok, so now we know that this can be done. Lets focus on the functionality.
I was wondering whether it is really logical that deep_ptr takes ownership=
=20
of the original pointer and that there is a make_deep_ptr function. Every=
=20
other copying step a copy of the source is made, so why not the first time?=
=20
Continuing this line of reasoning I was wondering whether it wouldn't be=20
appropriate to have an emplace<U>() method rather than make_deep_ptr=20
function for the first step. Maybe this brings it too close to std::any?
In the long run I think we have to consider how many such similar=20
constructs to have. I don't know exactly how std::any is supposed to work,=
=20
but I suspect that it is a non-template class which can hold a value of any=
=20
type and copies that value when itself is copied. Thus if it is initialized=
=20
from a pointer it will only copy the pointer rather than the pointee (which=
=20
makes cloning via base pointer a non-issue).
I'm suspecting that there are proposals for some kind of type_erased<T>=20
class where T is a baseclass of whatever object it hosts. Without=20
operator.() this may not be such an interesting proposal as it would have=
=20
to work as a pointer (access via ->) anyway, but with operator.() it seems=
=20
very nice. The question is what is the design space that a deep_ptr would=
=20
fill given these other constructs? It seems that deep_prt is a type_erased=
=20
without operator. but which acts more like a pointer when being initialized=
=20
(assuming that type_erased is inited via emplace<U>()).
Den s=C3=B6ndag 10 januari 2016 kl. 19:09:19 UTC+1 skrev Jonathan Coe:
>
>
> On 10 January 2016 at 17:43, Ville Voutilainen <ville.vo...@gmail.com=20
> <javascript:>> wrote:
>
>> On 10 January 2016 at 19:39, Jonathan Coe <jb...@me.com <javascript:>>=
=20
>> wrote:
>> >> > My implementation propagates constness. This is not necessary but t=
o=20
>> my
>> >> > mind
>> >> > makes sense as a deep_ptr is intended to extend the logical state o=
f=20
>> a
>> >> > object. What do others think?
>> >>
>> >> I am gravitating towards not propagating const in this type, since
>> >> other smart pointers
>> >> don't do that, and propagate_const can be applied on top.
>> > Agreed.
>>
>>
>> Another thing: const propagation is easy to slap on top with=20
>> propagate_const,
>> but if the type does it built-in and the user for whatever reason
>> doesn't want it,
>> bypassing the const propagation is.. ..interesting, to say the least,=20
>> right?
>>
>
> Agreed.
> =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:>.
>> Visit this group at=20
>> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_4838_1731395046.1452601633555
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Ok, so now we know that this can be done. Lets focus on th=
e functionality.<div><br></div><div>I was wondering whether it is really lo=
gical that deep_ptr takes ownership of the original pointer and that there =
is a make_deep_ptr function. Every other copying step a copy of the source =
is made, so why not the first time? Continuing this line of reasoning I was=
wondering whether it wouldn't be appropriate to have an emplace<U&g=
t;() method rather than make_deep_ptr function for the first step. Maybe th=
is brings it too close to std::any?</div><div><br></div><div>In the long ru=
n I think we have to consider how many such similar constructs to have. I d=
on't know exactly how std::any is supposed to work, but I suspect that =
it is a non-template class which can hold a value of any type and copies th=
at value when itself is copied. Thus if it is initialized from a pointer it=
will only copy the pointer rather than the pointee (which makes cloning vi=
a base pointer a non-issue).</div><div><br></div><div>I'm suspecting th=
at there are proposals for some kind of type_erased<T> class where T =
is a baseclass of whatever object it hosts. Without operator.() this may no=
t be such an interesting proposal as it would have to work as a pointer (ac=
cess via ->) anyway, but with operator.() it seems very nice. The questi=
on is what is the design space that a deep_ptr would fill given these other=
constructs? It seems that deep_prt is a type_erased without operator. but =
which acts more like a pointer when being initialized (assuming that type_e=
rased is inited via emplace<U>()).<br><br>Den s=C3=B6ndag 10 januari =
2016 kl. 19:09:19 UTC+1 skrev Jonathan Coe:<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><div>On 10 January 2016 at 17:43, Ville V=
outilainen <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" =
gdf-obfuscated-mailto=3D"3toPSAb1FAAJ" rel=3D"nofollow" onmousedown=3D"this=
..href=3D'javascript:';return true;" onclick=3D"this.href=3D'jav=
ascript:';return true;">ville.vo...@gmail.com</a>></span> wrote:<br>=
<div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On 10 Janua=
ry 2016 at 19:39, Jonathan Coe <<a href=3D"javascript:" target=3D"_blank=
" gdf-obfuscated-mailto=3D"3toPSAb1FAAJ" rel=3D"nofollow" onmousedown=3D"th=
is.href=3D'javascript:';return true;" onclick=3D"this.href=3D'j=
avascript:';return true;">jb...@me.com</a>> wrote:<br>
>> > My implementation propagates constness. This is not necessary=
but to my<br>
>> > mind<br>
>> > makes sense as a deep_ptr is intended to extend the logical s=
tate of a<br>
>> > object. What do others think?<br>
>><br>
>> I am gravitating towards not propagating const in this type, since=
<br>
>> other smart pointers<br>
>> don't do that, and propagate_const can be applied on top.<br>
> Agreed.<br>
<br>
<br>
</span>Another thing: const propagation is easy to slap on top with propaga=
te_const,<br>
but if the type does it built-in and the user for whatever reason<br>
doesn't want it,<br>
bypassing the const propagation is.. ..interesting, to say the least, right=
?<br></blockquote><div><br></div><div>Agreed.</div><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex">
<div><div><br>
--<br>
<br>
---<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"=
3toPSAb1FAAJ" 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"3toPSAb1FAAJ" 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>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.hre=
f=3D'https://groups.google.com/a/isocpp.org/group/std-proposals/';r=
eturn true;" onclick=3D"this.href=3D'https://groups.google.com/a/isocpp=
..org/group/std-proposals/';return true;">https://groups.google.com/a/<w=
br>isocpp.org/group/std-<wbr>proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
</blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_4838_1731395046.1452601633555--
------=_Part_4837_723397248.1452601633554--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Tue, 12 Jan 2016 15:18:56 +0200
Raw View
On 12 January 2016 at 14:27, Bengt Gustafsson
<bengt.gustafsson@beamways.com> wrote:
> Ok, so now we know that this can be done. Lets focus on the functionality.
> I was wondering whether it is really logical that deep_ptr takes ownership
> of the original pointer and that there is a make_deep_ptr function. Every
That happens to be convenient, to wrap dynamically allocated resources so that
they get cloned on copy.
> other copying step a copy of the source is made, so why not the first time?
Why would it perform such a pointless extra copy?
> In the long run I think we have to consider how many such similar constructs
> to have. I don't know exactly how std::any is supposed to work, but I
> suspect that it is a non-template class which can hold a value of any type
> and copies that value when itself is copied. Thus if it is initialized from
> a pointer it will only copy the pointer rather than the pointee (which makes
> cloning via base pointer a non-issue).
It makes any cloning a non-issue, since it won't clone anything, and is thus
not suitable for the purpose cloned_ptr serves.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Patrice Roy <patricer@gmail.com>
Date: Tue, 12 Jan 2016 22:40:04 -0500
Raw View
--047d7bdc15ea00fbc505292eed57
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
In an =C2=ABany=C2=BB implementation, the copying can be hidden internally =
in such a
way that non-cloneable types like int can be stored. For example, any can
have an internal cloneable class from which derived classes are type-aware
templates that know how to copy the stored value:
class any
{
struct hook
{
virtual hook * clone() const =3D 0;
virtual ~hook() =3D default;
};
template <class T>
class datum : public hook
{
T value;
datum * clone() const override { return new datum{ *this }; }
protected:
datum(const datum&) =3D default;
public:
datum(const T &value) : value{ value }
{ }
// ...
};
// ...
hook *p;
public:
template <class T>
any(const T & value)
: p { new datum<T>{ value } }
{
}
// ... :
};
The real design issue in an =C2=ABany=C2=BB type is retrieving the stored v=
alue (it
can be done with RTTI but that's not acceptable in some use cases). The
cloning is an internal issue that can be resolved without clone_ptr
(although if clone_ptr simplifies the pattern at no cost, then why not?).
2016-01-12 8:18 GMT-05:00 Ville Voutilainen <ville.voutilainen@gmail.com>:
> On 12 January 2016 at 14:27, Bengt Gustafsson
> <bengt.gustafsson@beamways.com> wrote:
> > Ok, so now we know that this can be done. Lets focus on the
> functionality.
> > I was wondering whether it is really logical that deep_ptr takes
> ownership
> > of the original pointer and that there is a make_deep_ptr function. Eve=
ry
>
> That happens to be convenient, to wrap dynamically allocated resources so
> that
> they get cloned on copy.
>
> > other copying step a copy of the source is made, so why not the first
> time?
>
> Why would it perform such a pointless extra copy?
>
> > In the long run I think we have to consider how many such similar
> constructs
> > to have. I don't know exactly how std::any is supposed to work, but I
> > suspect that it is a non-template class which can hold a value of any
> type
> > and copies that value when itself is copied. Thus if it is initialized
> from
> > a pointer it will only copy the pointer rather than the pointee (which
> makes
> > cloning via base pointer a non-issue).
>
> It makes any cloning a non-issue, since it won't clone anything, and is
> thus
> not suitable for the purpose cloned_ptr serves.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--047d7bdc15ea00fbc505292eed57
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div><div><div>In an =C2=ABany=C2=BB implementation, =
the copying can be hidden internally in such a way that non-cloneable types=
like int can be stored. For example, any can have an internal cloneable cl=
ass from which derived classes are type-aware templates that know how to co=
py the stored value:<br><br></div>class any<br>{<br></div>=C2=A0=C2=A0 stru=
ct hook<br>=C2=A0=C2=A0 {<br></div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 virtual h=
ook * clone() const =3D 0;<br></div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 virtual =
~hook() =3D default;<br><div><div>=C2=A0=C2=A0 };<br></div><div>=C2=A0=C2=
=A0 template <class T><br></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 c=
lass datum : public hook<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br></div><div>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 T value;<br></div><d=
iv>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 datum * clone() c=
onst override { return new datum{ *this }; }<br></div><div>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 protected:<br></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 datum(const datum&) =3D default;<br></div><div>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 public:<br></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 datum(const T &value)=C2=A0 : value{ value }<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 { }<br><=
/div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ...<br></div>=
<div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br>=C2=A0=C2=A0 // ...<br></div><div=
>=C2=A0=C2=A0 hook *p;<br></div><div>public:<br></div><div>=C2=A0=C2=A0 tem=
plate <class T><br></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 any(cons=
t T & value)<br></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 : p { new datum<T>{ value } }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0 // ... =C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 : <br></div><div><div>};<br><br></div><div>The real d=
esign issue in an =C2=ABany=C2=BB type is retrieving the stored value (it c=
an be done with RTTI but that's not acceptable in some use cases). The =
cloning is an internal issue that can be resolved without clone_ptr (althou=
gh if clone_ptr simplifies the pattern at no cost, then why not?).<br><br><=
/div><div><br></div></div></div></div><div class=3D"gmail_extra"><br><div c=
lass=3D"gmail_quote">2016-01-12 8:18 GMT-05:00 Ville Voutilainen <span dir=
=3D"ltr"><<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blan=
k">ville.voutilainen@gmail.com</a>></span>:<br><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex">On 12 January 2016 at 14:27, Bengt Gustafsson<br>
<span class=3D""><<a href=3D"mailto:bengt.gustafsson@beamways.com">bengt=
..gustafsson@beamways.com</a>> wrote:<br>
> Ok, so now we know that this can be done. Lets focus on the functional=
ity.<br>
> I was wondering whether it is really logical that deep_ptr takes owner=
ship<br>
> of the original pointer and that there is a make_deep_ptr function. Ev=
ery<br>
<br>
</span>That happens to be convenient, to wrap dynamically allocated resourc=
es so that<br>
they get cloned on copy.<br>
<span class=3D""><br>
> other copying step a copy of the source is made, so why not the first =
time?<br>
<br>
</span>Why would it perform such a pointless extra copy?<br>
<span class=3D""><br>
> In the long run I think we have to consider how many such similar cons=
tructs<br>
> to have. I don't know exactly how std::any is supposed to work, bu=
t I<br>
> suspect that it is a non-template class which can hold a value of any =
type<br>
> and copies that value when itself is copied. Thus if it is initialized=
from<br>
> a pointer it will only copy the pointer rather than the pointee (which=
makes<br>
> cloning via base pointer a non-issue).<br>
<br>
</span>It makes any cloning a non-issue, since it won't clone anything,=
and is thus<br>
not suitable for the purpose cloned_ptr serves.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
--<br>
<br>
---<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%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/group/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7bdc15ea00fbc505292eed57--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Wed, 13 Jan 2016 06:50:38 -0800 (PST)
Raw View
------=_Part_397_70926396.1452696638649
Content-Type: multipart/alternative;
boundary="----=_Part_398_90162672.1452696638650"
------=_Part_398_90162672.1452696638650
Content-Type: text/plain; charset=UTF-8
>
> That happens to be convenient, to wrap dynamically allocated resources so
> that
> they get cloned on copy.
>
> > other copying step a copy of the source is made, so why not the first
> time?
>
> Why would it perform such a pointless extra copy?
>
I think this is a matter of point of view. Maybe you have the data you want
to transport via the deep_ptr in a by value way. Maybe you can emplace it
directly into the deep_ptr. This aside I found a annoying use case which
indicates the way we may need to go: downcasting. We have discussed
upcasting a lot and the implications this has with multiple inheritance or
covariant return types. But take a look at downcasting. As we can't
downcast a smart pointer the usual way is to use get() to get the raw
pointer, downcast it and give it to the receptor:
deep_ptr<Base> bp = make_deep<Sub>();
deep_ptr<Sub> sp = static_cast<Sub*>(bp.get());
Problem #1: Noone copies the data.
Problem #2: If bp had contained a further subclass SubSub of Sub whomever
that tried to manually do the copy in the process would likely slice the
object into a Sub. There is no real way of knowing what subclass it is if
you just get the bp assumed to contain some sort of Sub.
One way of solving this would be to introduce a method:
template<typename U> deep_ptr<U> deep_ptr<T>::cast<U>()
This method would perform the copying itself and return the copy. On the
other hand, with my initial copying idea the classical idiom described
above would work.
A more exotic possiblity that sprung to my mind when thinking about this
would be to view static_cast and dynamic_cast as overloadable operators, so
that casting of smart pointers (including deep_ptr) could be written as for
plain pointers:
shared_ptr<Base> bp = new Base;
shared_ptr<Sub> sp = static_cast<shared_ptr<Sub>>(bp);
// A shot at how to write the definition:
template<typename T> class shared_ptr {
template<typename U> operator static_cast<shared_ptr<U>>() { return
shared_ptr<U>(--the control block-,
static_cast<U*>(get())); }
};
This is of course a separate proposal but I just wanted to see what the
reaction here might be. I didn't put must thought into how to actually
write the declaration.
Another idea was prompted by Patrice's writing on std::any. Here also a way
to specify cloning of incoming polymorphic data would be vital to avoid
slicing when initiating an std::any from a polymorphic baseclass reference
(I assume a copy is made here). We obviously don't want to have separate
systems to specify cloning methods for std::any, std::deep_ptr and possibly
std::type_erased_value. I see a few possibilities:
1. Allow virtual on copy constructors, similar to how it is allowed on
destructors. (The copy constructor being the one that can get implemented
automatically). While this is not really logical as the class of the new
object is taken from the parameter (there is no 'this' yet!) it would be
very easy to implement and very useful. The main problem is that it would
do a new so some kind of allocator support will be wished for. Also in some
cases you may want to slice the source, how can this be specified?
2. Define a std::clone() method* that can be overloaded by polymorphic base
classes with cloning needs. any, deep_ptr and type_erased finds the
implementation if there is one. The "namespace std:" so famous for
std::swap may occur, I guess. The main drawback however is that there is
nothing to prevent accidental non-overriding of the clone method in
subclasses (unless a must_override specifier is invented of course).
3. Define some other magic way than virtual on the baseclass copy ctor to
indicate clonability. A positional keyword after the class name maybe. Then
std::clone is magic in that it can access a hidden vtbl entry to do cloning
without slicing. To me this seems just like a more complicated way of
achieving 1.
* The default implementation can check against polymorphic calls using
typeid() in debug builds if desired:
template<typename T> T* std::clone(const T* src)
{
assert(typeid(*src) == typeid(T)); // Base case does not allow
subclasses as they can't be cloned without slicing
return new T(*src);
}
>
> > In the long run I think we have to consider how many such similar
> constructs
> > to have. I don't know exactly how std::any is supposed to work, but I
> > suspect that it is a non-template class which can hold a value of any
> type
> > and copies that value when itself is copied. Thus if it is initialized
> from
> > a pointer it will only copy the pointer rather than the pointee (which
> makes
> > cloning via base pointer a non-issue).
>
> It makes any cloning a non-issue, since it won't clone anything, and is
> thus
> not suitable for the purpose cloned_ptr serves.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_398_90162672.1452696638650
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<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;">That happens =
to be convenient, to wrap dynamically allocated resources so that
<br>they get cloned on copy.
<br>
<br>> other copying step a copy of the source is made, so why not the fi=
rst time?
<br>
<br>Why would it perform such a pointless extra copy?<br></blockquote><div>=
<br></div><div>I think this is a matter of point of view. Maybe you have th=
e data you want to transport via the deep_ptr in a by value way. Maybe you =
can emplace it directly into the deep_ptr. This aside I found a annoying us=
e case which indicates the way we may need to go: downcasting. We have disc=
ussed upcasting a lot and the implications this has with multiple inheritan=
ce or covariant return types. But take a look at downcasting. As we can'=
;t downcast a smart pointer the usual way is to use get() to get the raw po=
inter, downcast it and give it to the receptor:</div><div><br></div><div>de=
ep_ptr<Base> bp =3D make_deep<Sub>();</div><div>deep_ptr<Sub=
> sp =3D static_cast<Sub*>(bp.get());</div><div><br></div><div>=C2=
=A0Problem #1: Noone copies the data.</div><div>=C2=A0Problem #2: If bp had=
contained a further subclass SubSub of Sub whomever that tried to manually=
do the copy in the process would likely slice the object into a Sub. There=
is no real way of knowing what subclass it is if you just get the bp assum=
ed to contain some sort of Sub.</div><div><br></div><div>One way of solving=
this would be to introduce a method:</div><div><div class=3D"prettyprint" =
style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; backg=
round-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=
=C2=A0</span><span style=3D"color: #008;" class=3D"styled-by-prettify">temp=
late</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> U</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> deep_ptr</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">U</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> deep_ptr</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">>::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">cast</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
<</span><span style=3D"color: #000;" class=3D"styled-by-prettify">U</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">>()</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span></div></cod=
e></div><br></div><div>This method would perform the copying itself and ret=
urn the copy. On the other hand, with my initial copying idea the classical=
idiom described above would work.</div><div><br></div><div>A more exotic p=
ossiblity that sprung to my mind when thinking about this would be to view =
static_cast and dynamic_cast as overloadable operators, so that casting of =
smart pointers (including deep_ptr) could be written as for plain pointers:=
</div><div><br></div><div class=3D"prettyprint" style=3D"border: 1px solid =
rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, =
250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">shared_ptr</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Base</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> bp </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">new</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Base</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>shared_ptr</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Sub</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">></span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> sp </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">static_cast</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">shared_ptr</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify"><</span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Sub</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>=
;>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">bp</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><br></span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// A shot at how t=
o write the definition:</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">template</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">typename</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> shared_ptr </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> U</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">operator</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">static_cast</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">shared_ptr</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">U</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>&=
gt;()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> shared_ptr</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">U</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">>(--</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">the control block</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">-,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">static_cast</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">U</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">*>(</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">get</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
()));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></div><d=
iv><br>This is of course a separate proposal but I just wanted to see what =
the reaction here might be. I didn't put must thought into how to actua=
lly write the declaration.</div><div><br></div><div>Another idea was prompt=
ed by Patrice's writing on std::any. Here also a way to specify cloning=
of incoming polymorphic data would be vital to avoid slicing when initiati=
ng an std::any from a polymorphic baseclass reference (I assume a copy is m=
ade here). We obviously don't want to have separate systems to specify =
cloning methods for std::any, std::deep_ptr and possibly std::type_erased_v=
alue. I see a few possibilities:</div><div><br></div><div>1. Allow virtual =
on copy constructors, similar to how it is allowed on destructors. (The cop=
y constructor being the one that can get implemented automatically). While =
this is not really logical as the class of the new object is taken from the=
parameter (there is no 'this' yet!) it would be very easy to imple=
ment and very useful. The main problem is that it would do a new so some ki=
nd of allocator support will be wished for. Also in some cases you may want=
to slice the source, how can this be specified?</div><div><br></div><div>2=
.. Define a std::clone() method* that can be overloaded by polymorphic base =
classes with cloning needs. any, deep_ptr and type_erased finds the impleme=
ntation if there is one. The "namespace std:" so famous for std::=
swap may occur, I guess. The main drawback however is that there is nothing=
to prevent accidental non-overriding of the clone method in subclasses (un=
less a must_override specifier is invented of course).</div><div><br></div>=
<div>3. Define some other magic way than virtual on the baseclass copy ctor=
to indicate clonability. A positional keyword after the class name maybe. =
Then std::clone is magic in that it can access a hidden vtbl entry to do cl=
oning without slicing. To me this seems just like a more complicated way of=
achieving 1.</div><div><br></div><div><br></div><div>* The default impleme=
ntation can check against polymorphic calls using typeid() in debug builds =
if desired:</div><div><br></div><div><div class=3D"prettyprint" style=3D"bo=
rder: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color=
: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">template</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">clone</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">cons=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> src</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">typeid</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(*</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">src</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">typeid</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">));</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D=
"styled-by-prettify">// Base case does not allow subclasses as they can'=
;t be cloned without slicing</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">new</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">src=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></co=
de></div><br><br></div><div><br></div><div><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;">
<br></blockquote><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;">> In the long run I think we have to consider how many such simila=
r constructs
<br>> to have. I don't know exactly how std::any is supposed to work=
, but I
<br>> suspect that it is a non-template class which can hold a value of =
any type
<br>> and copies that value when itself is copied. Thus if it is initial=
ized from
<br>> a pointer it will only copy the pointer rather than the pointee (w=
hich makes
<br>> cloning via base pointer a non-issue).
<br>
<br>It makes any cloning a non-issue, since it won't clone anything, an=
d is thus
<br>not suitable for the purpose cloned_ptr serves.
<br></blockquote></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_398_90162672.1452696638650--
------=_Part_397_70926396.1452696638649--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 13 Jan 2016 17:05:30 +0200
Raw View
On 13 January 2016 at 16:50, Bengt Gustafsson
<bengt.gustafsson@beamways.com> wrote:
>> Why would it perform such a pointless extra copy?
> I think this is a matter of point of view. Maybe you have the data you want
> to transport via the deep_ptr in a by value way. Maybe you can emplace it
> directly into the deep_ptr. This aside I found a annoying use case which
> indicates the way we may need to go: downcasting. We have discussed
> upcasting a lot and the implications this has with multiple inheritance or
> covariant return types. But take a look at downcasting. As we can't downcast
> a smart pointer the usual way is to use get() to get the raw pointer,
> downcast it and give it to the receptor:
> deep_ptr<Base> bp = make_deep<Sub>();
> deep_ptr<Sub> sp = static_cast<Sub*>(bp.get());
Well, that's every bit as daft as using static_cast with a shared_ptr.
It won't work.
It needs a specialized cast that can do the right thing for the smart pointer.
None of that means that every adoption of a pointer should always
clone the incoming
value.
> One way of solving this would be to introduce a method:
> template<typename U> deep_ptr<U> deep_ptr<T>::cast<U>()
> This method would perform the copying itself and return the copy. On the
Yes, that seems like a very good approach.
> other hand, with my initial copying idea the classical idiom described above
> would work.
I don't find it a "classical idiom".
> A more exotic possiblity that sprung to my mind when thinking about this
> would be to view static_cast and dynamic_cast as overloadable operators, so
> that casting of smart pointers (including deep_ptr) could be written as for
> plain pointers:
>
> shared_ptr<Base> bp = new Base;
> shared_ptr<Sub> sp = static_cast<shared_ptr<Sub>>(bp);
>
>
> // A shot at how to write the definition:
>
>
> template<typename T> class shared_ptr {
> template<typename U> operator static_cast<shared_ptr<U>>() { return
> shared_ptr<U>(--the control block-,
>
> static_cast<U*>(get())); }
> };
>
>
> This is of course a separate proposal but I just wanted to see what the
> reaction here might be. I didn't put must thought into how to actually write
> the declaration.
If you want a generalized cast, that's attainable without having to
change static_cast
to be an operator.
> Another idea was prompted by Patrice's writing on std::any. Here also a way
> to specify cloning of incoming polymorphic data would be vital to avoid
> slicing when initiating an std::any from a polymorphic baseclass reference
> (I assume a copy is made here). We obviously don't want to have separate
> systems to specify cloning methods for std::any, std::deep_ptr and possibly
> std::type_erased_value. I see a few possibilities:
>
> 1. Allow virtual on copy constructors, similar to how it is allowed on
> destructors. (The copy constructor being the one that can get implemented
That continues to make no sense.
> automatically). While this is not really logical as the class of the new
> object is taken from the parameter (there is no 'this' yet!) it would be
> very easy to implement and very useful. The main problem is that it would do
Very easy to implement? How?
> 2. Define a std::clone() method* that can be overloaded by polymorphic base
> classes with cloning needs. any, deep_ptr and type_erased finds the
What purpose does it serve to define it in the standard? Which base class
would actually declare it?
> 3. Define some other magic way than virtual on the baseclass copy ctor to
> indicate clonability. A positional keyword after the class name maybe. Then
> std::clone is magic in that it can access a hidden vtbl entry to do cloning
> without slicing. To me this seems just like a more complicated way of
> achieving 1.
Well, "to indicate clonability", you either
1) make sure your class is valid for the default cloner (which means
CopyConstructible)
2) provide a custom cloner that does what you want
Why would we make wider changes to the language? Those cover a very large amount
of use cases in practice or even in imagination.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jonathan Coe <jonathanbcoe@gmail.com>
Date: Wed, 13 Jan 2016 15:29:03 +0000
Raw View
I have added support for static_pointer_cast, shared_pointer_cast and dynamic_pointer_cast to my reference implementation.
Jon
> On 13 Jan 2016, at 15:05, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
>
> On 13 January 2016 at 16:50, Bengt Gustafsson
> <bengt.gustafsson@beamways.com> wrote:
>>> Why would it perform such a pointless extra copy?
>> I think this is a matter of point of view. Maybe you have the data you want
>> to transport via the deep_ptr in a by value way. Maybe you can emplace it
>> directly into the deep_ptr. This aside I found a annoying use case which
>> indicates the way we may need to go: downcasting. We have discussed
>> upcasting a lot and the implications this has with multiple inheritance or
>> covariant return types. But take a look at downcasting. As we can't downcast
>> a smart pointer the usual way is to use get() to get the raw pointer,
>> downcast it and give it to the receptor:
>> deep_ptr<Base> bp = make_deep<Sub>();
>> deep_ptr<Sub> sp = static_cast<Sub*>(bp.get());
>
> Well, that's every bit as daft as using static_cast with a shared_ptr.
> It won't work.
> It needs a specialized cast that can do the right thing for the smart pointer.
> None of that means that every adoption of a pointer should always
> clone the incoming
> value.
>
>> One way of solving this would be to introduce a method:
>> template<typename U> deep_ptr<U> deep_ptr<T>::cast<U>()
>> This method would perform the copying itself and return the copy. On the
>
> Yes, that seems like a very good approach.
>
>> other hand, with my initial copying idea the classical idiom described above
>> would work.
>
> I don't find it a "classical idiom".
>
>> A more exotic possiblity that sprung to my mind when thinking about this
>> would be to view static_cast and dynamic_cast as overloadable operators, so
>> that casting of smart pointers (including deep_ptr) could be written as for
>> plain pointers:
>>
>> shared_ptr<Base> bp = new Base;
>> shared_ptr<Sub> sp = static_cast<shared_ptr<Sub>>(bp);
>>
>>
>> // A shot at how to write the definition:
>>
>>
>> template<typename T> class shared_ptr {
>> template<typename U> operator static_cast<shared_ptr<U>>() { return
>> shared_ptr<U>(--the control block-,
>>
>> static_cast<U*>(get())); }
>> };
>>
>>
>> This is of course a separate proposal but I just wanted to see what the
>> reaction here might be. I didn't put must thought into how to actually write
>> the declaration.
>
> If you want a generalized cast, that's attainable without having to
> change static_cast
> to be an operator.
>
>> Another idea was prompted by Patrice's writing on std::any. Here also a way
>> to specify cloning of incoming polymorphic data would be vital to avoid
>> slicing when initiating an std::any from a polymorphic baseclass reference
>> (I assume a copy is made here). We obviously don't want to have separate
>> systems to specify cloning methods for std::any, std::deep_ptr and possibly
>> std::type_erased_value. I see a few possibilities:
>>
>> 1. Allow virtual on copy constructors, similar to how it is allowed on
>> destructors. (The copy constructor being the one that can get implemented
>
> That continues to make no sense.
>
>> automatically). While this is not really logical as the class of the new
>> object is taken from the parameter (there is no 'this' yet!) it would be
>> very easy to implement and very useful. The main problem is that it would do
>
> Very easy to implement? How?
>
>> 2. Define a std::clone() method* that can be overloaded by polymorphic base
>> classes with cloning needs. any, deep_ptr and type_erased finds the
>
> What purpose does it serve to define it in the standard? Which base class
> would actually declare it?
>
>> 3. Define some other magic way than virtual on the baseclass copy ctor to
>> indicate clonability. A positional keyword after the class name maybe. Then
>> std::clone is magic in that it can access a hidden vtbl entry to do cloning
>> without slicing. To me this seems just like a more complicated way of
>> achieving 1.
>
> Well, "to indicate clonability", you either
> 1) make sure your class is valid for the default cloner (which means
> CopyConstructible)
> 2) provide a custom cloner that does what you want
>
> Why would we make wider changes to the language? Those cover a very large amount
> of use cases in practice or even in imagination.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 23 Jan 2016 01:55:02 -0800 (PST)
Raw View
------=_Part_2621_2110638059.1453542902145
Content-Type: multipart/alternative;
boundary="----=_Part_2622_159630532.1453542902146"
------=_Part_2622_159630532.1453542902146
Content-Type: text/plain; charset=UTF-8
Jon, you made it perfectly clear why overloadable static_cast and
dynamic_cast are desirable. You now introduced three different names for
just one of these casts (I don't know why, really) but wouldn't it be much
better to be able to overload the current names with functions for other
data types (typically smart pointers). My earlier suggestion to do this in
the class head was maybe not the wisest choice, a free function overload
seems more logical in retrospect.
template<typename T, typename U> shared_ptr<T> static_cast(const shared_ptr<
U>& src)
{
return shared_ptr<T>(static_cast<T*>(src.get()); // In reality
shared_ptr would need to share the control block ptr.
}
While it is currently possible to static_cast a shared_ptr if you for some
reason inherit a class from it, introducing the above would cause compile
time error for those cases, so it is not that bad.
The basic principle for such a feature would work as operator,(): If no
user defined cast function can be found the current, built in cast is used.
As for the built in clone functionality I maintain it is quite simple to
implement, but maybe not *as* simple as I thought at the time. The issue is
that when you create a subclass object it will likely be larger than the
baseclass object you have the pointer/reference to. Also, to avoid breaking
code that is deliberately slicing the incoming reference we need to
differentiate the syntax from the case where slciing is desired:
Base* slice(Base* src)
{
return new Base(*src);
}
One way of doing this is to offer a 'virtual new' like this:
Base* clone(Base* src)
{
return virtual new Base(*src);
}
this means that operator new reaches into the vtbl of src to find a) the
size of the malloc block to get, and b) the address of the copy ctor of the
runtime class of src. While this works for regular new it is problematic
for placement new as you supposedly conjure up a suitably sized malloc
block before newing, but how to know its size? We could allow 'virtual
sizeof' to handle this:
Base* placement_clone(Base* src)
{
char* addr = new char[virtual sizeof(*src)];
return virtual new(addr) Base(*src);
}
Note that we still need virtual new to get the right copy ctor.
I see this as a workable solution, but I don't like that 'virtual new base'
actually constructs some other class, which is non-intuitive. As
alternatives there could be a std::clone() function with magic properties
or type_info could be augmented with size() and copy_construct() methods:
Base* typeid_clone(Base* src)
{
char* addr = new char[typeid(*src).size()];
return typeid(*src).copy_construct(addr, src); // copy_construct must
return a Base* as it may be offset from addr*.
}
A design decision is whether the two vtbl entries pointing to the copy ctor
and the size are to be added as soon as a class has a virtual method (as
for the type_info pointer) or only if the base class copy ctor is declared
virtual (as for the destructor). I would lean towards the automatic option
despite its slight overhead even if not used.
Another possibility is to just wait for the reflection functionality to
materialize, which seems to be a long wait. Also, AFAIK the reflection will
only be at compile time which doesn't help this situation.
*) copy_construct (or virtual new) must use the same information that
dynamic_cast does to find out the offset from the actual type of src to
Base after creating the copy. I haven't looked into if there could be some
insurmountable problem with Base being a virtual base of *src's runtime
type but I don't think it should be any worse than dynamic_cast.
Whatever language feature is at the root of this functionality I suspect
that a std::clone() is the logical user visible API to present to
programmers. to do a 'placement clone' you'd have to fall back on the
language's basic functionality.
So in fact we are looking at three proposals here: deep_ptr as such, smart
pointer casts and cloning. I don't think it would be wise to write them
into one paper.
Den onsdag 13 januari 2016 kl. 16:29:15 UTC+1 skrev Jonathan Coe:
>
> I have added support for static_pointer_cast, shared_pointer_cast and
> dynamic_pointer_cast to my reference implementation.
>
> Jon
>
> > On 13 Jan 2016, at 15:05, Ville Voutilainen <ville.vo...@gmail.com
> <javascript:>> wrote:
> >
> > On 13 January 2016 at 16:50, Bengt Gustafsson
> > <bengt.gu...@beamways.com <javascript:>> wrote:
> >>> Why would it perform such a pointless extra copy?
> >> I think this is a matter of point of view. Maybe you have the data you
> want
> >> to transport via the deep_ptr in a by value way. Maybe you can emplace
> it
> >> directly into the deep_ptr. This aside I found a annoying use case
> which
> >> indicates the way we may need to go: downcasting. We have discussed
> >> upcasting a lot and the implications this has with multiple inheritance
> or
> >> covariant return types. But take a look at downcasting. As we can't
> downcast
> >> a smart pointer the usual way is to use get() to get the raw pointer,
> >> downcast it and give it to the receptor:
> >> deep_ptr<Base> bp = make_deep<Sub>();
> >> deep_ptr<Sub> sp = static_cast<Sub*>(bp.get());
> >
> > Well, that's every bit as daft as using static_cast with a shared_ptr.
> > It won't work.
> > It needs a specialized cast that can do the right thing for the smart
> pointer.
> > None of that means that every adoption of a pointer should always
> > clone the incoming
> > value.
> >
> >> One way of solving this would be to introduce a method:
> >> template<typename U> deep_ptr<U> deep_ptr<T>::cast<U>()
> >> This method would perform the copying itself and return the copy. On
> the
> >
> > Yes, that seems like a very good approach.
> >
> >> other hand, with my initial copying idea the classical idiom described
> above
> >> would work.
> >
> > I don't find it a "classical idiom".
> >
> >> A more exotic possiblity that sprung to my mind when thinking about
> this
> >> would be to view static_cast and dynamic_cast as overloadable
> operators, so
> >> that casting of smart pointers (including deep_ptr) could be written as
> for
> >> plain pointers:
> >>
> >> shared_ptr<Base> bp = new Base;
> >> shared_ptr<Sub> sp = static_cast<shared_ptr<Sub>>(bp);
> >>
> >>
> >> // A shot at how to write the definition:
> >>
> >>
> >> template<typename T> class shared_ptr {
> >> template<typename U> operator static_cast<shared_ptr<U>>() { return
> >> shared_ptr<U>(--the control block-,
> >>
> >> static_cast<U*>(get())); }
> >> };
> >>
> >>
> >> This is of course a separate proposal but I just wanted to see what the
> >> reaction here might be. I didn't put must thought into how to actually
> write
> >> the declaration.
> >
> > If you want a generalized cast, that's attainable without having to
> > change static_cast
> > to be an operator.
> >
> >> Another idea was prompted by Patrice's writing on std::any. Here also a
> way
> >> to specify cloning of incoming polymorphic data would be vital to avoid
> >> slicing when initiating an std::any from a polymorphic baseclass
> reference
> >> (I assume a copy is made here). We obviously don't want to have
> separate
> >> systems to specify cloning methods for std::any, std::deep_ptr and
> possibly
> >> std::type_erased_value. I see a few possibilities:
> >>
> >> 1. Allow virtual on copy constructors, similar to how it is allowed on
> >> destructors. (The copy constructor being the one that can get
> implemented
> >
> > That continues to make no sense.
> >
> >> automatically). While this is not really logical as the class of the
> new
> >> object is taken from the parameter (there is no 'this' yet!) it would
> be
> >> very easy to implement and very useful. The main problem is that it
> would do
> >
> > Very easy to implement? How?
> >
> >> 2. Define a std::clone() method* that can be overloaded by polymorphic
> base
> >> classes with cloning needs. any, deep_ptr and type_erased finds the
> >
> > What purpose does it serve to define it in the standard? Which base
> class
> > would actually declare it?
> >
> >> 3. Define some other magic way than virtual on the baseclass copy ctor
> to
> >> indicate clonability. A positional keyword after the class name maybe.
> Then
> >> std::clone is magic in that it can access a hidden vtbl entry to do
> cloning
> >> without slicing. To me this seems just like a more complicated way of
> >> achieving 1.
> >
> > Well, "to indicate clonability", you either
> > 1) make sure your class is valid for the default cloner (which means
> > CopyConstructible)
> > 2) provide a custom cloner that does what you want
> >
> > Why would we make wider changes to the language? Those cover a very
> large amount
> > of use cases in practice or even in imagination.
> >
> > --
> >
> > ---
> > 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-proposal...@isocpp.org <javascript:>.
> > To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>
> > Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2622_159630532.1453542902146
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Jon, you made it perfectly clear why overloadable static_c=
ast and dynamic_cast are desirable. You now introduced three different name=
s for just one of these casts (I don't know why, really) but wouldn'=
;t it be much better to be able to overload the current names with function=
s for other data types (typically smart pointers). My earlier suggestion to=
do this in the class head was maybe not the wisest choice, a free function=
overload seems more logical in retrospect.<div><br></div><div class=3D"pre=
ttyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-w=
ord; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> U</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> shared_ptr</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">static_cast</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">cons=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> shared_p=
tr</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">U</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">>&</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> src</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> shared_ptr</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">>(</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">static_cast</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*>=
;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">src</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">get</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">());</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" =
class=3D"styled-by-prettify">// In reality shared_ptr would need to share t=
he control block ptr.</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br></span></div></code></div><div><br>While it is currently possible to st=
atic_cast a shared_ptr if you for some reason inherit a class from it, intr=
oducing the above would cause compile time error for those cases, so it is =
not that bad.<br><br>The basic principle for such a feature would work as o=
perator,(): If no user defined cast function can be found the current, buil=
t in cast is used.</div><div><br></div><div>As for the built in clone funct=
ionality I maintain it is quite simple to implement, but maybe not <i>as</i=
> simple as I thought at the time. The issue is that when you create a subc=
lass object it will likely be larger than the baseclass object you have the=
pointer/reference to. Also, to avoid breaking code that is deliberately sl=
icing the incoming reference we need to differentiate the syntax from the c=
ase where slciing is desired:</div><div><br></div><div class=3D"prettyprint=
" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; bac=
kground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">Base</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> slice</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Base</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> src</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
new</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Base</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">(*</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">src</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span></div></code></div><div><br><br></div><div>=
One way of doing this is to offer a 'virtual new' like this:</div><=
div><br></div><div><div class=3D"prettyprint" style=3D"border: 1px solid rg=
b(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 25=
0);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Base</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> clone</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">Base</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> src</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">virtual</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">new</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">Base</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">src</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></cod=
e></div><div><br></div></div><div>this means that operator new reaches into=
the vtbl of src to find a) the size of the malloc block to get, and b) the=
address of the copy ctor of the runtime class of src. While this works for=
regular new it is problematic for placement new as you supposedly conjure =
up a suitably sized malloc block before newing, but how to know its size? W=
e could allow 'virtual sizeof' to handle this:</div><div><br><span =
class=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(10=
2, 0, 102); background-color: rgb(250, 250, 250);">Base</span><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(102, 10=
2, 0); background-color: rgb(250, 250, 250);">*</span><span class=3D"styled=
-by-prettify" style=3D"font-family: monospace; color: rgb(0, 0, 0); backgro=
und-color: rgb(250, 250, 250);">=C2=A0placement_clone</span><span class=3D"=
styled-by-prettify" style=3D"font-family: monospace; color: rgb(102, 102, 0=
); background-color: rgb(250, 250, 250);">(</span><span class=3D"styled-by-=
prettify" style=3D"font-family: monospace; color: rgb(102, 0, 102); backgro=
und-color: rgb(250, 250, 250);">Base</span><span class=3D"styled-by-prettif=
y" style=3D"font-family: monospace; color: rgb(102, 102, 0); background-col=
or: rgb(250, 250, 250);">*</span><span class=3D"styled-by-prettify" style=
=3D"font-family: monospace; color: rgb(0, 0, 0); background-color: rgb(250,=
250, 250);">=C2=A0src</span><span class=3D"styled-by-prettify" style=3D"fo=
nt-family: monospace; color: rgb(102, 102, 0); background-color: rgb(250, 2=
50, 250);">)</span><span class=3D"styled-by-prettify" style=3D"font-family:=
monospace; color: rgb(0, 0, 0); background-color: rgb(250, 250, 250);"><br=
></span><span class=3D"styled-by-prettify" style=3D"font-family: monospace;=
color: rgb(102, 102, 0); background-color: rgb(250, 250, 250);">{</span></=
div><div><span class=3D"styled-by-prettify" style=3D"font-family: monospace=
; background-color: rgb(250, 250, 250);"><font color=3D"#666600">=C2=A0 =C2=
=A0 char* addr =3D new char[virtual sizeof(*src)];<br></font><font color=3D=
"#000000">=C2=A0 =C2=A0=C2=A0</font></span><span class=3D"styled-by-prettif=
y" style=3D"font-family: monospace; color: rgb(0, 0, 136); background-color=
: rgb(250, 250, 250);">return</span><span class=3D"styled-by-prettify" styl=
e=3D"font-family: monospace; color: rgb(0, 0, 0); background-color: rgb(250=
, 250, 250);">=C2=A0</span><span class=3D"styled-by-prettify" style=3D"font=
-family: monospace; color: rgb(0, 0, 136); background-color: rgb(250, 250, =
250);">virtual</span><span class=3D"styled-by-prettify" style=3D"font-famil=
y: monospace; color: rgb(0, 0, 0); background-color: rgb(250, 250, 250);">=
=C2=A0</span><span class=3D"styled-by-prettify" style=3D"font-family: monos=
pace; color: rgb(0, 0, 136); background-color: rgb(250, 250, 250);">new(add=
r)</span><span class=3D"styled-by-prettify" style=3D"font-family: monospace=
; color: rgb(0, 0, 0); background-color: rgb(250, 250, 250);">=C2=A0</span>=
<span class=3D"styled-by-prettify" style=3D"font-family: monospace; color: =
rgb(102, 0, 102); background-color: rgb(250, 250, 250);">Base</span><span c=
lass=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(102=
, 102, 0); background-color: rgb(250, 250, 250);">(*</span><span class=3D"s=
tyled-by-prettify" style=3D"font-family: monospace; color: rgb(0, 0, 0); ba=
ckground-color: rgb(250, 250, 250);">src</span><span class=3D"styled-by-pre=
ttify" style=3D"font-family: monospace; color: rgb(102, 102, 0); background=
-color: rgb(250, 250, 250);">);</span><span class=3D"styled-by-prettify" st=
yle=3D"font-family: monospace; color: rgb(0, 0, 0); background-color: rgb(2=
50, 250, 250);"><br></span><span class=3D"styled-by-prettify" style=3D"font=
-family: monospace; color: rgb(102, 102, 0); background-color: rgb(250, 250=
, 250);">}</span></div><div><br></div><div>Note that we still need virtual =
new to get the right copy ctor.</div><div><br></div><div>I see this as a wo=
rkable solution, but I don't like that 'virtual new base' actua=
lly constructs some other class, which is non-intuitive. As alternatives th=
ere could be a std::clone() function with magic properties or type_info cou=
ld be augmented with size() and copy_construct() methods:</div><div><br></d=
iv><div><div><span class=3D"styled-by-prettify" style=3D"font-family: monos=
pace; color: rgb(102, 0, 102); background-color: rgb(250, 250, 250);">Base<=
/span><span class=3D"styled-by-prettify" style=3D"font-family: monospace; c=
olor: rgb(102, 102, 0); background-color: rgb(250, 250, 250);">*</span><spa=
n class=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(=
0, 0, 0); background-color: rgb(250, 250, 250);">=C2=A0typeid_clone</span><=
span class=3D"styled-by-prettify" style=3D"font-family: monospace; color: r=
gb(102, 102, 0); background-color: rgb(250, 250, 250);">(</span><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(102, 0,=
102); background-color: rgb(250, 250, 250);">Base</span><span class=3D"sty=
led-by-prettify" style=3D"font-family: monospace; color: rgb(102, 102, 0); =
background-color: rgb(250, 250, 250);">*</span><span class=3D"styled-by-pre=
ttify" style=3D"font-family: monospace; color: rgb(0, 0, 0); background-col=
or: rgb(250, 250, 250);">=C2=A0src</span><span class=3D"styled-by-prettify"=
style=3D"font-family: monospace; color: rgb(102, 102, 0); background-color=
: rgb(250, 250, 250);">)</span><span class=3D"styled-by-prettify" style=3D"=
font-family: monospace; color: rgb(0, 0, 0); background-color: rgb(250, 250=
, 250);"><br></span><span class=3D"styled-by-prettify" style=3D"font-family=
: monospace; color: rgb(102, 102, 0); background-color: rgb(250, 250, 250);=
">{</span></div><div><span class=3D"styled-by-prettify" style=3D"font-famil=
y: monospace; background-color: rgb(250, 250, 250);"><font color=3D"#666600=
">=C2=A0 =C2=A0 char* addr =3D new char[typeid(*src).size()];<br></font><fo=
nt color=3D"#000000">=C2=A0 =C2=A0=C2=A0</font></span><span class=3D"styled=
-by-prettify" style=3D"font-family: monospace; color: rgb(0, 0, 136); backg=
round-color: rgb(250, 250, 250);">return</span><span class=3D"styled-by-pre=
ttify" style=3D"font-family: monospace; color: rgb(0, 0, 0); background-col=
or: rgb(250, 250, 250);">=C2=A0</span><span class=3D"styled-by-prettify" st=
yle=3D"font-family: monospace; background-color: rgb(250, 250, 250);"><font=
color=3D"#000088">typeid(*src).copy_construct(addr, src); // copy_construc=
t must return a Base* as it may be offset from addr*.</font></span></div><d=
iv><span class=3D"styled-by-prettify" style=3D"font-family: monospace; colo=
r: rgb(102, 102, 0); background-color: rgb(250, 250, 250);">}</span></div><=
/div><div><span class=3D"styled-by-prettify" style=3D"font-family: monospac=
e; color: rgb(102, 102, 0); background-color: rgb(250, 250, 250);"><br></sp=
an></div><div><br></div><div>A design decision is whether the two vtbl entr=
ies pointing to the copy ctor and the size are to be added as soon as a cla=
ss has a virtual method (as for the type_info pointer) or only if the base =
class copy ctor is declared virtual (as for the destructor). I would lean t=
owards the automatic option despite its slight overhead even if not used.</=
div><div><br></div><div>Another possibility is to just wait for the reflect=
ion functionality to materialize, which seems to be a long wait. Also, AFAI=
K the reflection will only be at compile time which doesn't help this s=
ituation.=C2=A0</div><div><br></div><div>*) copy_construct (or virtual new)=
must use the same information that dynamic_cast does to find out the offse=
t from the actual type of src to Base after creating the copy. I haven'=
t looked into if there could be some insurmountable problem with Base being=
a virtual base of *src's runtime type but I don't think it should =
be any worse than dynamic_cast.</div><div><br></div><div>Whatever language =
feature is at the root of this functionality I suspect that a std::clone() =
is the logical user visible API to present to programmers. to do a 'pla=
cement clone' you'd have to fall back on the language's basic f=
unctionality.</div><div><br></div><div>So in fact we are looking at three p=
roposals here: deep_ptr as such, smart pointer casts and cloning. I don'=
;t think it would be wise to write them into one paper.</div><div><br></div=
><div>Den onsdag 13 januari 2016 kl. 16:29:15 UTC+1 skrev Jonathan Coe:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">I have added support for static_po=
inter_cast, shared_pointer_cast and dynamic_pointer_cast to my reference im=
plementation.
<br>
<br>Jon
<br>
<br>> On 13 Jan 2016, at 15:05, Ville Voutilainen <<a href=3D"javascr=
ipt:" target=3D"_blank" gdf-obfuscated-mailto=3D"If4r_wfYFQAJ" rel=3D"nofol=
low" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;">ville.vo...@gmail.com</=
a>> wrote:
<br>>=20
<br>> On 13 January 2016 at 16:50, Bengt Gustafsson
<br>> <<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"If4r_wfYFQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascr=
ipt:';return true;" onclick=3D"this.href=3D'javascript:';return=
true;">bengt.gu...@beamways.com</a><wbr>> wrote:
<br>>>> Why would it perform such a pointless extra copy?
<br>>> I think this is a matter of point of view. Maybe you have the =
data you want
<br>>> to transport via the deep_ptr in a by value way. Maybe you can=
emplace it
<br>>> directly into the deep_ptr. This aside I found a annoying use =
case which
<br>>> indicates the way we may need to go: downcasting. We have disc=
ussed
<br>>> upcasting a lot and the implications this has with multiple in=
heritance or
<br>>> covariant return types. But take a look at downcasting. As we =
can't downcast
<br>>> a smart pointer the usual way is to use get() to get the raw p=
ointer,
<br>>> downcast it and give it to the receptor:
<br>>> deep_ptr<Base> bp =3D make_deep<Sub>();
<br>>> deep_ptr<Sub> sp =3D static_cast<Sub*>(bp.get());
<br>>=20
<br>> Well, that's every bit as daft as using static_cast with a sha=
red_ptr.
<br>> It won't work.
<br>> It needs a specialized cast that can do the right thing for the sm=
art pointer.
<br>> None of that means that every adoption of a pointer should always
<br>> clone the incoming
<br>> value.
<br>>=20
<br>>> One way of solving this would be to introduce a method:
<br>>> template<typename U> deep_ptr<U> deep_ptr<T>=
::cast<U>()
<br>>> This method would perform the copying itself and return the co=
py. On the
<br>>=20
<br>> Yes, that seems like a very good approach.
<br>>=20
<br>>> other hand, with my initial copying idea the classical idiom d=
escribed above
<br>>> would work.
<br>>=20
<br>> I don't find it a "classical idiom".
<br>>=20
<br>>> A more exotic possiblity that sprung to my mind when thinking =
about this
<br>>> would be to view static_cast and dynamic_cast as overloadable =
operators, so
<br>>> that casting of smart pointers (including deep_ptr) could be w=
ritten as for
<br>>> plain pointers:
<br>>>=20
<br>>> shared_ptr<Base> bp =3D new Base;
<br>>> shared_ptr<Sub> sp =3D static_cast<shared_ptr<Sub&=
gt;>(<wbr>bp);
<br>>>=20
<br>>>=20
<br>>> // A shot at how to write the definition:
<br>>>=20
<br>>>=20
<br>>> template<typename T> class shared_ptr {
<br>>> =C2=A0 =C2=A0template<typename U> operator static_cast&l=
t;shared_ptr<U>>() { return
<br>>> shared_ptr<U>(--the control block-,
<br>>>=20
<br>>> static_cast<U*>(get())); }
<br>>> };
<br>>>=20
<br>>>=20
<br>>> This is of course a separate proposal but I just wanted to see=
what the
<br>>> reaction here might be. I didn't put must thought into how=
to actually write
<br>>> the declaration.
<br>>=20
<br>> If you want a generalized cast, that's attainable without havi=
ng to
<br>> change static_cast
<br>> to be an operator.
<br>>=20
<br>>> Another idea was prompted by Patrice's writing on std::any=
.. Here also a way
<br>>> to specify cloning of incoming polymorphic data would be vital=
to avoid
<br>>> slicing when initiating an std::any from a polymorphic basecla=
ss reference
<br>>> (I assume a copy is made here). We obviously don't want to=
have separate
<br>>> systems to specify cloning methods for std::any, std::deep_ptr=
and possibly
<br>>> std::type_erased_value. I see a few possibilities:
<br>>>=20
<br>>> 1. Allow virtual on copy constructors, similar to how it is al=
lowed on
<br>>> destructors. (The copy constructor being the one that can get =
implemented
<br>>=20
<br>> That continues to make no sense.
<br>>=20
<br>>> automatically). While this is not really logical as the class =
of the new
<br>>> object is taken from the parameter (there is no 'this'=
yet!) it would be
<br>>> very easy to implement and very useful. The main problem is th=
at it would do
<br>>=20
<br>> Very easy to implement? How?
<br>>=20
<br>>> 2. Define a std::clone() method* that can be overloaded by pol=
ymorphic base
<br>>> classes with cloning needs. any, deep_ptr and type_erased find=
s the
<br>>=20
<br>> What purpose does it serve to define it in the standard? Which bas=
e class
<br>> would actually declare it?
<br>>=20
<br>>> 3. Define some other magic way than virtual on the baseclass c=
opy ctor to
<br>>> indicate clonability. A positional keyword after the class nam=
e maybe. Then
<br>>> std::clone is magic in that it can access a hidden vtbl entry =
to do cloning
<br>>> without slicing. To me this seems just like a more complicated=
way of
<br>>> achieving 1.
<br>>=20
<br>> Well, "to indicate clonability", you either
<br>> 1) make sure your class is valid for the default cloner (which mea=
ns
<br>> CopyConstructible)
<br>> 2) provide a custom cloner that does what you want
<br>>=20
<br>> Why would we make wider changes to the language? Those cover a ver=
y large amount
<br>> of use cases in practice or even in imagination.
<br>>=20
<br>> --=20
<br>>=20
<br>> ---=20
<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 email to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"If4r_wfYFQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;">std-proposal...@<wbr>isocpp.org</a>.
<br>> To post to this group, send email to <a href=3D"javascript:" targe=
t=3D"_blank" gdf-obfuscated-mailto=3D"If4r_wfYFQAJ" rel=3D"nofollow" onmous=
edown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.hr=
ef=3D'javascript:';return true;">std-pr...@isocpp.org</a>.
<br>> Visit this group at <a href=3D"https://groups.google.com/a/isocpp.=
org/group/std-proposals/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D=
"this.href=3D'https://groups.google.com/a/isocpp.org/group/std-proposal=
s/';return true;" onclick=3D"this.href=3D'https://groups.google.com=
/a/isocpp.org/group/std-proposals/';return true;">https://groups.google=
..com/a/<wbr>isocpp.org/group/std-<wbr>proposals/</a>.
<br></blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_2622_159630532.1453542902146--
------=_Part_2621_2110638059.1453542902145--
.
Author: Nevin Liber <nevin@cplusplusguy.com>
Date: Sat, 23 Jan 2016 04:21:01 -0600
Raw View
--001a11409fc2a9feab0529fdb311
Content-Type: text/plain; charset=UTF-8
On 23 January 2016 at 03:55, Bengt Gustafsson <bengt.gustafsson@beamways.com
> wrote:
> Jon, you made it perfectly clear why overloadable static_cast and
> dynamic_cast are desirable. You now introduced three different names for
> just one of these casts
>
What three names? static_pointer_cast and dynamic_pointer_cast are already
part of the shared_ptr interface, have been since its introduction in
C++11, as well as for many years before that as part of Boost shared_ptr.
You really ought to look at the current smart pointers in the standard
before attempting to propose a new one.
> (I don't know why, really) but wouldn't it be much better to be able to
> overload the current names with functions for other data types (typically
> smart pointers).
>
Why invent a complicated language feature if we can not only get by w/o it,
but the library feature is easily extended to other smart pointers not
provided by the standard.
>
> As for the built in clone functionality I maintain it is quite simple to
> implement, but maybe not *as* simple as I thought at the time.
>
If it is "quite simple", do you have an implementation we can try?
> One way of doing this is to offer a 'virtual new' like this:
>
*sigh*
So in fact we are looking at three proposals here: deep_ptr as such, smart
> pointer casts and cloning. I don't think it would be wise to write them
> into one paper.
>
Jonathan can do the pure LEWG proposal of deep_ptr and *_pointer_casts
(like for shared_ptr, they do go together) and leave the "quite simple"
language changes to you. How does that sound?
--
Nevin ":-)" Liber <mailto:nevin@cplusplusguy.com <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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11409fc2a9feab0529fdb311
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 23 January 2016 at 03:55, Bengt Gustafsson <span dir=3D=
"ltr"><<a href=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank=
">bengt.gustafsson@beamways.com</a>></span> wrote:<br><div class=3D"gmai=
l_extra"><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">Jon, you made it perfectly clear why overloadable static_cast and =
dynamic_cast are desirable. You now introduced three different names for ju=
st one of these casts</div></blockquote><div><br></div><div>What three name=
s? =C2=A0static_pointer_cast and dynamic_pointer_cast are already part of t=
he shared_ptr interface, have been since its introduction in C++11, as well=
as for many years before that as part of Boost shared_ptr.</div><div><br><=
/div><div>You really ought to look at the current smart pointers in the sta=
ndard before attempting to propose a new one.</div><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"> (I don't know why, really) bu=
t wouldn't it be much better to be able to overload the current names w=
ith functions for other data types (typically smart pointers).</div></block=
quote><div><br></div><div>Why invent a complicated language feature if we c=
an not only get by w/o it, but the library feature is easily extended to ot=
her smart pointers not provided by the standard.</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"><div><br></div><div>As for the built in clone fu=
nctionality I maintain it is quite simple to implement, but maybe not <i>as=
</i> simple as I thought at the time.</div></div></blockquote><div><br></di=
v><div>If it is "quite simple", do you have an implementation we =
can try?</div><div>=C2=A0</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"><div>One way of doing this is to offer a 'virtual new' like thi=
s:<br></div></div></blockquote><div><br></div><div>*sigh*</div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>So in fact we are l=
ooking at three proposals here: deep_ptr as such, smart pointer casts and c=
loning. I don't think it would be wise to write them into one paper.<br=
></div></div></blockquote><div><br></div><div>Jonathan can do the pure LEWG=
proposal of deep_ptr and *_pointer_casts (like for shared_ptr, they do go =
together) and leave the "quite simple" language changes to you.=
=C2=A0 How does that sound?<br>-- <br><div class=3D"gmail_signature"><div d=
ir=3D"ltr">=C2=A0Nevin ":-)" Liber=C2=A0 <mailto:<a href=3D"ma=
ilto:nevin@eviloverlord.com" target=3D"_blank">nevin@cplusplusguy.com</a>&g=
t;=C2=A0 +1-847-691-1404<br></div></div>
</div></div></div>
</div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a11409fc2a9feab0529fdb311--
.
Author: Jonathan Coe <jbcoe@me.com>
Date: Sun, 24 Jan 2016 09:28:58 +0000
Raw View
--001a1137f1b4fde8b6052a1114ce
Content-Type: text/plain; charset=UTF-8
On 23 January 2016 at 10:21, Nevin Liber <nevin@cplusplusguy.com> wrote:
> On 23 January 2016 at 03:55, Bengt Gustafsson <
> bengt.gustafsson@beamways.com> wrote:
>
>> Jon, you made it perfectly clear why overloadable static_cast and
>> dynamic_cast are desirable. You now introduced three different names for
>> just one of these casts
>>
>
> What three names? static_pointer_cast and dynamic_pointer_cast are
> already part of the shared_ptr interface, have been since its introduction
> in C++11, as well as for many years before that as part of Boost shared_ptr.
>
> You really ought to look at the current smart pointers in the standard
> before attempting to propose a new one.
>
>
>> (I don't know why, really) but wouldn't it be much better to be able to
>> overload the current names with functions for other data types (typically
>> smart pointers).
>>
>
> Why invent a complicated language feature if we can not only get by w/o
> it, but the library feature is easily extended to other smart pointers not
> provided by the standard.
>
>>
>> As for the built in clone functionality I maintain it is quite simple to
>> implement, but maybe not *as* simple as I thought at the time.
>>
>
> If it is "quite simple", do you have an implementation we can try?
>
>
>> One way of doing this is to offer a 'virtual new' like this:
>>
>
> *sigh*
>
> So in fact we are looking at three proposals here: deep_ptr as such, smart
>> pointer casts and cloning. I don't think it would be wise to write them
>> into one paper.
>>
>
> Jonathan can do the pure LEWG proposal of deep_ptr and *_pointer_casts
> (like for shared_ptr, they do go together) and leave the "quite simple"
> language changes to you. How does that sound?
>
My plan is to keep deep_ptr a pure library proposal and to keep is as close
in design to shared_ptr as possible.
Please note that my reference implementation currently lags behind the
draft paper I'm working on - I'll be sure to post once I update the code.
Jon
>
> --
> Nevin ":-)" Liber <mailto:nevin@cplusplusguy.com
> <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.
> Visit this group at
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a1137f1b4fde8b6052a1114ce
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On 23 January 2016 at 10:21, Nevin Liber <span dir=3D"ltr"><<a href=
=3D"mailto:nevin@cplusplusguy.com" target=3D"_blank">nevin@cplusplusguy.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"><=
span class=3D"">On 23 January 2016 at 03:55, Bengt Gustafsson <span dir=3D"=
ltr"><<a href=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank"=
>bengt.gustafsson@beamways.com</a>></span> wrote:<br></span><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D""><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr">Jon, you made it perfectly clear why over=
loadable static_cast and dynamic_cast are desirable. You now introduced thr=
ee different names for just one of these casts</div></blockquote><div><br><=
/div></span><div>What three names? =C2=A0static_pointer_cast and dynamic_po=
inter_cast are already part of the shared_ptr interface, have been since it=
s introduction in C++11, as well as for many years before that as part of B=
oost shared_ptr.</div><div><br></div><div>You really ought to look at the c=
urrent smart pointers in the standard before attempting to propose a new on=
e.</div><span class=3D""><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"> (I don't know why, really) but wouldn't it be much =
better to be able to overload the current names with functions for other da=
ta types (typically smart pointers).</div></blockquote><div><br></div></spa=
n><div>Why invent a complicated language feature if we can not only get by =
w/o it, but the library feature is easily extended to other smart pointers =
not provided by the standard.</div><span class=3D""><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div><br></div><div>As for the built in clone func=
tionality I maintain it is quite simple to implement, but maybe not <i>as</=
i> simple as I thought at the time.</div></div></blockquote><div><br></div>=
</span><div>If it is "quite simple", do you have an implementatio=
n we can try?</div><span class=3D""><div>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>One way of doing this is to offer a 'vir=
tual new' like this:<br></div></div></blockquote><div><br></div></span>=
<div>*sigh*</div><span class=3D""><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"><div>So in fact we are looking at three proposals her=
e: deep_ptr as such, smart pointer casts and cloning. I don't think it =
would be wise to write them into one paper.<br></div></div></blockquote><di=
v><br></div></span><div>Jonathan can do the pure LEWG proposal of deep_ptr =
and *_pointer_casts (like for shared_ptr, they do go together) and leave th=
e "quite simple" language changes to you.=C2=A0 How does that sou=
nd?</div></div></div></div></blockquote><div><br></div><div>My plan is to k=
eep deep_ptr a pure library proposal and to keep is as close in design to s=
hared_ptr as possible.</div><div><br></div><div>Please note that my referen=
ce implementation currently lags behind the draft paper I'm working on =
- I'll be sure to post once I update the code.</div><div><br></div><div=
>Jon</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><span class=3D"H=
OEnZb"><font color=3D"#888888"><br>-- <br><div><div dir=3D"ltr">=C2=A0Nevin=
":-)" Liber=C2=A0 <mailto:<a href=3D"mailto:nevin@eviloverlor=
d.com" target=3D"_blank">nevin@cplusplusguy.com</a>>=C2=A0 <a href=3D"te=
l:%2B1-847-691-1404" value=3D"+18476911404" target=3D"_blank">+1-847-691-14=
04</a><br></div></div>
</font></span></div></div></div>
</div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/" target=3D"_blank">https://groups.google.com/a/isocpp.org/g=
roup/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a1137f1b4fde8b6052a1114ce--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sun, 24 Jan 2016 06:45:51 -0800 (PST)
Raw View
------=_Part_31_815439458.1453646751139
Content-Type: multipart/alternative;
boundary="----=_Part_32_699048376.1453646751139"
------=_Part_32_699048376.1453646751139
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
well, I was confused by Jon's typo, he wrote shared_pointer_cast as one of=
=20
his names, where I suppose it should have been const_pointer_cast. Also, he=
=20
failed to mention that these were overloads of existing functions for=20
shared pointers.
Nevertheless, I had never seen these, which still sort of points at the=20
inconvenience of not being able to overload the more well known static_cast=
=20
names. In the teaching situation it may be an uphill battle to get students=
=20
to understand that to cast a pointer you use static_cast while to cast a=20
smart pointer (which is actually a class) you use static_pointer_cast. this=
=20
said, it is of course less motivated to take the trouble of writing a=20
proposal in the light of established function names parallel to the built=
=20
in operators.
You are *sighing* at the hard problems with cloning I have supposedly=20
missed, and there may indeed be such problems, I have only been a C++=20
programmer for 22 years, what do I know. It would however be slightly more=
=20
constructive to give a little hint at what the problems that are so hard to=
=20
overcome might be. While you're at it you may care to describe in layman's=
=20
words why letting typeid(value) returning a metaclass object with more=20
complete functionality than the current type_info is such an impossibly=20
ridiculous idea that a totally different RTTI system has to be invented in=
=20
som distant future.
If you are not able to convince me that implementing cloning (maybe using=
=20
type_info extensions) is very hard I may indeed take a stab at implementing=
=20
it in Clang and writing a proposal.
Jonathan. I understand your urge to make this a pure library feature, this=
=20
is always easiest. I do think that the deep_ptr poses some new issues=20
regarding polymorphic cloning that makes it much more useful with this in=
=20
the language. These issues don't appear with shared_ptr which doesn't do=20
cloning, or with std::any() which does not have as polymorphic looking an=
=20
API, although it is quite easy to happen to slice the object with an any=20
too it happens immediately on the construction of the any object and can be=
=20
detected using the typeid equality test.
Den l=C3=B6rdag 23 januari 2016 kl. 11:21:44 UTC+1 skrev Nevin Liber:
>
> On 23 January 2016 at 03:55, Bengt Gustafsson <bengt.gu...@beamways.com=
=20
> <javascript:>> wrote:
>
>> Jon, you made it perfectly clear why overloadable static_cast and=20
>> dynamic_cast are desirable. You now introduced three different names for=
=20
>> just one of these casts
>>
>
> What three names? static_pointer_cast and dynamic_pointer_cast are=20
> already part of the shared_ptr interface, have been since its introductio=
n=20
> in C++11, as well as for many years before that as part of Boost shared_p=
tr.
>
> You really ought to look at the current smart pointers in the standard=20
> before attempting to propose a new one.
> =20
>
>> (I don't know why, really) but wouldn't it be much better to be able to=
=20
>> overload the current names with functions for other data types (typicall=
y=20
>> smart pointers).
>>
>
> Why invent a complicated language feature if we can not only get by w/o=
=20
> it, but the library feature is easily extended to other smart pointers no=
t=20
> provided by the standard.
>
>>
>> As for the built in clone functionality I maintain it is quite simple to=
=20
>> implement, but maybe not *as* simple as I thought at the time.
>>
>
> If it is "quite simple", do you have an implementation we can try?
> =20
>
>> One way of doing this is to offer a 'virtual new' like this:
>>
>
> *sigh*
>
> So in fact we are looking at three proposals here: deep_ptr as such, smar=
t=20
>> pointer casts and cloning. I don't think it would be wise to write them=
=20
>> into one paper.
>>
>
> Jonathan can do the pure LEWG proposal of deep_ptr and *_pointer_casts=20
> (like for shared_ptr, they do go together) and leave the "quite simple"=
=20
> language changes to you. How does that sound?
> --=20
> Nevin ":-)" Liber <mailto:ne...@cplusplusguy.com <javascript:>> =20
> +1-847-691-1404
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_32_699048376.1453646751139
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">well, I was confused by Jon's typo, he wrote shared_po=
inter_cast as one of his names, where I suppose it should have been const_p=
ointer_cast. Also, he failed to mention that these were overloads of existi=
ng functions for shared pointers.<div><br></div><div>Nevertheless, I had ne=
ver seen these, which still sort of points at the inconvenience of not bein=
g able to overload the more well known static_cast names. In the teaching s=
ituation it may be an uphill battle to get students to understand that to c=
ast a pointer you use static_cast while to cast a smart pointer (which is a=
ctually a class) you use static_pointer_cast. this said, it is of course le=
ss motivated to take the trouble of writing a proposal in the light of esta=
blished function names parallel to the built in operators.</div><div><br></=
div><div>You are *sighing* at the hard problems with cloning I have suppose=
dly missed, and there may indeed be such problems, I have only been a C++ p=
rogrammer for 22 years, what do I know. It would however be slightly more c=
onstructive to give a little hint at what the problems that are so hard to =
overcome might be. While you're at it you may care to describe in layma=
n's words why letting typeid(value) returning a metaclass object with m=
ore complete functionality than the current type_info is such an impossibly=
ridiculous idea that a totally different RTTI system has to be invented in=
som distant future.</div><div><br></div><div>If you are not able to convin=
ce me that implementing cloning (maybe using type_info extensions) is very =
hard I may indeed take a stab at implementing it in Clang and writing a pro=
posal.</div><div><br></div><div>Jonathan. I understand your urge to make th=
is a pure library feature, this is always easiest. I do think that the deep=
_ptr poses some new issues regarding polymorphic cloning that makes it much=
more useful with this in the language. These issues don't appear with =
shared_ptr which doesn't do cloning, or with std::any() which does not =
have as polymorphic looking an API, although it is quite easy to happen to =
slice the object with an any too it happens immediately on the construction=
of the any object and can be detected using the typeid equality test.</div=
><div><br><br>Den l=C3=B6rdag 23 januari 2016 kl. 11:21:44 UTC+1 skrev Nevi=
n Liber:<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 23=
January 2016 at 03:55, Bengt Gustafsson <span dir=3D"ltr"><<a href=3D"j=
avascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"pWp3oA3ZGAAJ" rel=3D=
"nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" o=
nclick=3D"this.href=3D'javascript:';return true;">bengt.gu...@beamw=
ays.com</a><wbr>></span> wrote:<br><div><div class=3D"gmail_quote"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr">Jon, you made it perfectly clear=
why overloadable static_cast and dynamic_cast are desirable. You now intro=
duced three different names for just one of these casts</div></blockquote><=
div><br></div><div>What three names? =C2=A0static_pointer_cast and dynamic_=
pointer_cast are already part of the shared_ptr interface, have been since =
its introduction in C++11, as well as for many years before that as part of=
Boost shared_ptr.</div><div><br></div><div>You really ought to look at the=
current smart pointers in the standard before attempting to propose a new =
one.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
(I don't know why, really) but wouldn't it be much better to be ab=
le to overload the current names with functions for other data types (typic=
ally smart pointers).</div></blockquote><div><br></div><div>Why invent a co=
mplicated language feature if we can not only get by w/o it, but the librar=
y feature is easily extended to other smart pointers not provided by the st=
andard.</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div=
><div>As for the built in clone functionality I maintain it is quite simple=
to implement, but maybe not <i>as</i> simple as I thought at the time.</di=
v></div></blockquote><div><br></div><div>If it is "quite simple",=
do you have an implementation we can try?</div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex"><div dir=3D"ltr"><div>One way of doing this is to offe=
r a 'virtual new' like this:<br></div></div></blockquote><div><br><=
/div><div>*sigh*</div><div><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>So in fact we are looking at three proposals here: deep_ptr =
as such, smart pointer casts and cloning. I don't think it would be wis=
e to write them into one paper.<br></div></div></blockquote><div><br></div>=
<div>Jonathan can do the pure LEWG proposal of deep_ptr and *_pointer_casts=
(like for shared_ptr, they do go together) and leave the "quite simpl=
e" language changes to you.=C2=A0 How does that sound?<br>-- <br><div>=
<div dir=3D"ltr">=C2=A0Nevin ":-)" Liber=C2=A0 <mailto:<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"pWp3oA3ZGAAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return tru=
e;" onclick=3D"this.href=3D'javascript:';return true;">ne...@cplusp=
lusguy.com</a><wbr>>=C2=A0 +1-847-691-1404<br></div></div>
</div></div></div>
</div>
</blockquote></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_32_699048376.1453646751139--
------=_Part_31_815439458.1453646751139--
.
Author: Nevin Liber <nevin@cplusplusguy.com>
Date: Mon, 25 Jan 2016 16:00:25 -0600
Raw View
--001a113ecd9a92ab91052a2fb4d2
Content-Type: text/plain; charset=UTF-8
On 24 January 2016 at 08:45, Bengt Gustafsson <bengt.gustafsson@beamways.com
> wrote:
> Also, he failed to mention that these were overloads of existing functions
> for shared pointers.
>
I don't think it is the job of this proposal to teach people about
shared_ptr. I most certainly expect the people in LEWG who would be
evaluating this proposal to know enough about shared_ptr, unique_ptr and
even observer_ptr to make an informed decision on whether or not to accept
this proposal and what its interface should be to fit in with the rest of
the standard library.
And it isn't like we haven't pointed you to shared_ptr *numerous times* in
this discussion.
> Nevertheless, I had never seen these, which still sort of points at the
> inconvenience of not being able to overload the more well known static_cast
> names. In the teaching situation it may be an uphill battle to get students
> to understand that to cast a pointer you use static_cast while to cast a
> smart pointer (which is actually a class) you use static_pointer_cast.
>
If you want this behavior, make a separate proposal. Or make a library
proposal for *_pointer_cast to work with raw pointers.
> You are *sighing* at the hard problems with cloning I have supposedly
> missed, and there may indeed be such problems, I have only been a C++
> programmer for 22 years, what do I know. It would however be slightly more
> constructive to give a little hint at what the problems that are so hard to
> overcome might be.
>
You keep telling us it is simple *without proof*. For instance:
Many other languages support the eqivalent of a virtual copy ctor, and it
> would be simple to add to C++.
If you think it is so simple, describe its behavior. Does it work like
regular virtual functions? If so, how do you guarantee that base objects
are constructed? Can it be abstract? Is there a compiler generated one,
and if so, what does it look like? Does it break anything just to put the
word "virtual" in front of a copy constructor?
Again, if this is so simple, you should be able to answer these questions
with ease.
Or we could take your "quite simple" virtual new. Placement new is used to
construct objects *whose type and size are known at compile time.* virtual
new makes that a run time decision. That sounds like something which has
far reaching consequences for the language, and not like something that is
"quite simple".
Please describe the quite simple behavior of virtual new and the impact on
people who currently use placement new and prove me wrong.
--
Nevin ":-)" Liber <mailto:nevin@cplusplusguy.com <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.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113ecd9a92ab91052a2fb4d2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 24 January 2016 at 08:45, Bengt Gustafsson <span dir=3D=
"ltr"><<a href=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank=
">bengt.gustafsson@beamways.com</a>></span> wrote:<br><div class=3D"gmai=
l_extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(20=
4,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">Also,=
he failed to mention that these were overloads of existing functions for s=
hared pointers.</div></blockquote><div><br></div><div>I don't think it =
is the job of this proposal to teach people about shared_ptr.=C2=A0 I most =
certainly expect the people in LEWG who would be evaluating this proposal t=
o know enough about shared_ptr, unique_ptr and even observer_ptr to make an=
informed decision on whether or not to accept this proposal and what its i=
nterface should be to fit in with the rest of the standard library.</div><d=
iv><br></div><div>And it isn't like we haven't pointed you to share=
d_ptr <i>numerous times</i>=C2=A0in this discussion.</div><div>=C2=A0</div>=
<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-left-style:solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>Nevertheless, I had never seen these=
, which still sort of points at the inconvenience of not being able to over=
load the more well known static_cast names. In the teaching situation it ma=
y be an uphill battle to get students to understand that to cast a pointer =
you use static_cast while to cast a smart pointer (which is actually a clas=
s) you use static_pointer_cast.</div></div></blockquote><div><br></div><div=
>If you want this behavior, make a separate proposal.=C2=A0 Or make a libra=
ry proposal for *_pointer_cast to work with raw pointers.</div><div>=C2=A0<=
br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex"><div dir=3D"ltr"><div>You are *sighing* at the ha=
rd problems with cloning I have supposedly missed, and there may indeed be =
such problems, I have only been a C++ programmer for 22 years, what do I kn=
ow. It would however be slightly more constructive to give a little hint at=
what the problems that are so hard to overcome might be.</div></div></bloc=
kquote><div><br></div><div>You keep telling us it is simple <i>without proo=
f</i>.=C2=A0 For instance:</div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-c=
olor:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style=
=3D"font-size:13px">Many other languages support the eqivalent of a virtual=
copy ctor, and it would be simple to add to C++.=C2=A0</span></blockquote>=
<div><span style=3D"font-size:13px"><br></span></div><div>If you think it i=
s so simple, describe its behavior.=C2=A0 Does it work like regular virtual=
functions?=C2=A0 If so, how do you guarantee that base objects are constru=
cted?=C2=A0 Can it be abstract?=C2=A0 Is there a compiler generated one, an=
d if so, what does it look like?=C2=A0 Does it break anything just to put t=
he word "virtual" in front of a copy constructor?</div><div><br><=
/div><div>Again, if this is so simple, you should be able to answer these q=
uestions with ease.</div><div><br></div><div>Or we could take your "qu=
ite simple" virtual new.=C2=A0 Placement new is used to construct obje=
cts <i>whose type and size are known at compile time.</i>=C2=A0 virtual new=
makes that a run time decision.=C2=A0 That sounds like something which has=
far reaching consequences for the language, and not like something that is=
"quite simple".</div><div><br></div><div>Please describe the qui=
te simple behavior of virtual new and the impact on people who currently us=
e placement new and prove me wrong.</div></div>-- <br><div class=3D"gmail_s=
ignature"><div dir=3D"ltr">=C2=A0Nevin ":-)" Liber=C2=A0 <mail=
to:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@cplusp=
lusguy.com</a>>=C2=A0 +1-847-691-1404<br></div></div>
</div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a113ecd9a92ab91052a2fb4d2--
.