Topic: Slight extension to shared_ptr to convert to unique_ptr
Author: DeadMG <wolfeinstein@gmail.com>
Date: Wed, 19 Dec 2012 02:41:41 -0800 (PST)
Raw View
------=_Part_499_33057446.1355913701873
Content-Type: text/plain; charset=ISO-8859-1
One of the things that annoys me about the Standard ownership classes is
that you have to choose which one you want ahead of time. Sometimes this is
fine, but sometimes it's rather annoying.
So I propose std::unique_ptr<T, std::function<void(T*)>>.
Principally, I believe this already functions for most cases. The primary
issue is that shared_ptr cannot convert. I suggest that shared_ptr have an
explicit conversion (operator?) to unique_ptr<T, implementation-defined>,
where the deleter manages the reference count. This way, unique_ptrs with
type-erased or templated deleters can represent any ownership scheme.
--
------=_Part_499_33057446.1355913701873
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
One of the things that annoys me about the Standard ownership classes is th=
at you have to choose which one you want ahead of time. Sometimes this is f=
ine, but sometimes it's rather annoying.<div><br></div><div>So I propose st=
d::unique_ptr<T, std::function<void(T*)>>.</div><div><br></div>=
<div>Principally, I believe this already functions for most cases. The prim=
ary issue is that shared_ptr cannot convert. I suggest that shared_ptr have=
an explicit conversion (operator?) to unique_ptr<T, implementation-defi=
ned>, where the deleter manages the reference count. This way, unique_pt=
rs with type-erased or templated deleters can represent any ownership schem=
e.</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_499_33057446.1355913701873--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Wed, 19 Dec 2012 12:01:02 +0100
Raw View
2012/12/19 DeadMG <wolfeinstein@gmail.com>:
> One of the things that annoys me about the Standard ownership classes is
> that you have to choose which one you want ahead of time. Sometimes this is
> fine, but sometimes it's rather annoying.
>
> So I propose std::unique_ptr<T, std::function<void(T*)>>.
Why is the binding to std::function<void(T*)> so very important? You can already
instantiate this template now:
#include <functional>
#include <memory>
template<class T>
using my_ptr = std::unique_ptr<T, std::function<void(T*)>>;
struct S {};
int main() {
my_ptr<int> pi(new int(12));
my_ptr<S> ps(new S{});
}
> Principally, I believe this already functions for most cases. The primary
> issue is that shared_ptr cannot convert. I suggest that shared_ptr have an
> explicit conversion (operator?) to unique_ptr<T, implementation-defined>,
> where the deleter manages the reference count. This way, unique_ptrs with
> type-erased or templated deleters can represent any ownership scheme.
This would violate the contract of shared_ptr and unique_ptr. unique_ptr has the
invariant, that only one pointer owns the resource. You cannot
guarantee this (in general)
after with a shared_ptr as source, which may have multiple copies.
Please take a look at
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#1031
If you have answers to the questions asked then I suggest to create
a proposal paper. Ensure that you reference LWG issue 1031 and expect
that people will ask critical questions in regard to invariants and
implement-ability.
- Daniel
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Wed, 19 Dec 2012 03:46:46 -0800 (PST)
Raw View
------=_Part_160_11822441.1355917606581
Content-Type: text/plain; charset=ISO-8859-1
A unique_ptr constructed from a shared_ptr does not own the resource that
the shared_ptr owns. It owns *one strong reference to* that resource. It,
essentially, acts like a shared_ptr<T> but cannot be copied. The
implementation-defined deleter object acts like the destructor of a
shared_ptr.
How does one handle custom deleters given to the shared_ptr constructor?
The deleter holds a strong reference to the control block the source
shared_ptr is using, which holds the shared_ptr's deleter, along with the
reference count and whatnot.
What is the interface for such a conversion when the shared_ptr does not
> have unique ownership? Throw an exception? Create a null unique_ptr?
> Undefined behavior?
The same as for any other time.
--
------=_Part_160_11822441.1355917606581
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
A unique_ptr constructed from a shared_ptr does not own the resource that t=
he shared_ptr owns. It owns <i>one strong reference to</i> that resource. I=
t, essentially, acts like a shared_ptr<T> but cannot be copied. The i=
mplementation-defined deleter object acts like the destructor of a shared_p=
tr.<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0p=
x 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204);=
border-left-style: solid; padding-left: 1ex;"><span style=3D"color: rgb(0,=
0, 0); font-family: 'Times New Roman'; font-size: medium; text-align: just=
ify;">How does one handle custom deleters given to the </span><tt styl=
e=3D"color: rgb(0, 0, 0); text-align: justify;">shared_ptr</tt><span style=
=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: medium;=
text-align: justify;"> constructor?</span></blockquote><div><br></div=
><div>The deleter holds a strong reference to the control block the source =
shared_ptr is using, which holds the shared_ptr's deleter, along with the r=
eference count and whatnot.</div><div><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-l=
eft-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;=
"><span style=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-=
size: medium; text-align: justify;">What is the interface for such a conver=
sion when the </span><tt style=3D"color: rgb(0, 0, 0); text-align: jus=
tify;">shared_ptr</tt><span style=3D"color: rgb(0, 0, 0); font-family: 'Tim=
es New Roman'; font-size: medium; text-align: justify;"> does not have=
unique ownership? Throw an exception? Create a null </span><tt style=
=3D"color: rgb(0, 0, 0); text-align: justify;">unique_ptr</tt><span style=
=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: medium;=
text-align: justify;">? Undefined behavior?</span></blockquote><div><br></=
div><div>The same as for any other time.</div><div><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_160_11822441.1355917606581--
.
Author: Peter Sommerlad <peter.sommerlad@hsr.ch>
Date: Thu, 20 Dec 2012 10:02:17 +0100
Raw View
why would you want to prohibit copying a shared_ptr? unique_ptr can not ser=
ve that role IMHO
On 19.12.2012, at 12:46, DeadMG wrote:
> A unique_ptr constructed from a shared_ptr does not own the resource that=
the shared_ptr owns. It owns one strong reference to that resource. It, es=
sentially, acts like a shared_ptr<T> but cannot be copied. The implementati=
on-defined deleter object acts like the destructor of a shared_ptr.
>=20
> How does one handle custom deleters given to the shared_ptr constructor?
>=20
> The deleter holds a strong reference to the control block the source shar=
ed_ptr is using, which holds the shared_ptr's deleter, along with the refer=
ence count and whatnot.
>=20
> What is the interface for such a conversion when the shared_ptr does not =
have unique ownership? Throw an exception? Create a null unique_ptr? Undefi=
ned behavior?
>=20
> The same as for any other time.
>=20
>=20
> --=20
> =20
> =20
> =20
--=20
Prof. Peter Sommerlad
Institut f=FCr Software: Bessere Software - Einfach, Schneller!
HSR Hochschule f=FCr Technik Rapperswil
Oberseestr 10, Postfach 1475, CH-8640 Rapperswil
http://ifs.hsr.ch http://cute-test.com http://linticator.com http://includa=
tor.com
tel:+41 55 222 49 84 =3D=3D mobile:+41 79 432 23 32
fax:+41 55 222 46 29 =3D=3D mailto:peter.sommerlad@hsr.ch
--=20
.
Author: Mateusz Loskot <mateusz@loskot.net>
Date: Thu, 20 Dec 2012 11:38:10 +0000
Raw View
On 19 December 2012 11:46, DeadMG <wolfeinstein@gmail.com> wrote:
> A unique_ptr constructed from a shared_ptr does not own the resource that
> the shared_ptr owns. It owns one strong reference to that resource. It,
> essentially, acts like a shared_ptr<T> but cannot be copied.
This sounds like a significant change to the unique_ptr semantic,
which retains sole ownership of object.
IMO, you simply ask for a different type of smart pointer
a noncopyable std::strong_ptr ?
Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 20 Dec 2012 03:39:45 -0800 (PST)
Raw View
------=_Part_1288_6575651.1356003585520
Content-Type: text/plain; charset=ISO-8859-1
It retains sole ownership of an object- the strong reference.
--
------=_Part_1288_6575651.1356003585520
Content-Type: text/html; charset=ISO-8859-1
It retains sole ownership of an object- the strong reference.
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1288_6575651.1356003585520--
.
Author: Sebastian Gesemann <s.gesemann@gmail.com>
Date: Thu, 20 Dec 2012 13:23:53 +0100
Raw View
On Wed, Dec 19, 2012 at 11:41 AM, DeadMG wrote:
> One of the things that annoys me about the Standard ownership classes is
> that you have to choose which one you want ahead of time.
It's part of the design, so, of course you have to choose this in advance.
> So I propose std::unique_ptr<T, std::function<void(T*)>>.
>
> Principally, I believe this already functions for most cases. The primary
> issue is that shared_ptr cannot convert. I suggest that shared_ptr have an
> explicit conversion (operator?) to unique_ptr<T, implementation-defined>,
> where the deleter manages the reference count. This way, unique_ptrs with
> type-erased or templated deleters can represent any ownership scheme.
This does not seem to be a compelling case. It's not clear what
semantics it is supposed to have and how it can be implemented. What
do you mean by "where the deleter manages the reference count"? In
what situations do you want to allow such conversion? Are there any
constraints and/or preconditions to this conversion? Are you proposing
this conversion to always "work" or only in case the source
shared_ptr<T> is an rvalue and invoking its unique() member function
yields true?
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 20 Dec 2012 04:42:30 -0800 (PST)
Raw View
------=_Part_364_27020206.1356007350791
Content-Type: text/plain; charset=ISO-8859-1
>
> In what situations do you want to allow such conversion?
>
All of them. The conversion behaves like a copy of the source shared_ptr in
every respect, and is just as valid. It can be implemented fairly easily.
In fact, it's more than possible to implement shared_ptr on top of
unique_ptr.
What do you mean by "where the deleter manages the reference count"
The implementation-defined deleter in the result deals with decrementing
the reference count, and possibly deleting the object- that is, it acts
like ~shared_ptr(), effectively.
--
------=_Part_364_27020206.1356007350791
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"> In what situations =
do you want to allow such conversion?<br></blockquote><div><br></div><div>A=
ll of them. The conversion behaves like a copy of the source shared_pt=
r in every respect, and is just as valid. It can be implemented fairly easi=
ly. In fact, it's more than possible to implement shared_ptr on top of uniq=
ue_ptr.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, =
204, 204); border-left-style: solid; padding-left: 1ex;">What do you m=
ean by "where the deleter manages the reference count"</blockquote><div><br=
></div><div>The implementation-defined deleter in the result deals with dec=
rementing the reference count, and possibly deleting the object- that is, i=
t acts like ~shared_ptr(), effectively. </div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_364_27020206.1356007350791--
.
Author: Sebastian Gesemann <s.gesemann@gmail.com>
Date: Thu, 20 Dec 2012 13:52:25 +0100
Raw View
On Thu, Dec 20, 2012 at 1:42 PM, DeadMG wrote:
>> In what situations do you want to allow such conversion?
>
> All of them. The conversion behaves like a copy of the source shared_ptr in
> every respect, and is just as valid. It can be implemented fairly easily. In
> fact, it's more than possible to implement shared_ptr on top of unique_ptr.
>
>> What do you mean by "where the deleter manages the reference count"
>
> The implementation-defined deleter in the result deals with decrementing the
> reference count, and possibly deleting the object- that is, it acts like
> ~shared_ptr(), effectively.
What would be the point of doing that? The resulting unique_ptr object
would not be the unique owner. But unique ownership is kind of the
point of having a unique_ptr. Sorry, but this does not make any sense
to me. For some reason you want to have a unique_ptr that acts as a
shared_ptr for no apparent benefit.
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 20 Dec 2012 05:04:03 -0800 (PST)
Raw View
------=_Part_380_31914094.1356008643988
Content-Type: text/plain; charset=ISO-8859-1
It is the unique owner of one strong reference. And the principle benefit
is that it would now be possible to write a function that takes any kind of
pointer at run-time. The others are more easily achieved with custom
deleters, but shared_ptr needs some special support.
--
------=_Part_380_31914094.1356008643988
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
It is the unique owner of one strong reference. And the principle benefit i=
s that it would now be possible to write a function that takes any kind of =
pointer at run-time. The others are more easily achieved with custom delete=
rs, but shared_ptr needs some special support.
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_380_31914094.1356008643988--
.
Author: Sebastian Gesemann <s.gesemann@gmail.com>
Date: Thu, 20 Dec 2012 14:19:20 +0100
Raw View
On Thu, Dec 20, 2012 at 2:04 PM, DeadMG <wolfeinstein@gmail.com> wrote:
> It is the unique owner of one strong reference.
A shared_ptr is also "the unique owner of one strong reference". I
don't understand why you want to write "unique_ptr" and use it like a
shared_ptr.
> And the principle benefit is
> that it would now be possible to write a function that takes any kind of
> pointer at run-time.
How? To do what with it?
> The others are more easily achieved with custom
> deleters, but shared_ptr needs some special support.
Not convinced at all. And unless that changes somehow, you won't hear
from me on this topic again.
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 20 Dec 2012 05:39:20 -0800 (PST)
Raw View
------=_Part_1318_12295923.1356010760244
Content-Type: text/plain; charset=ISO-8859-1
>
> A shared_ptr is also "the unique owner of one strong reference".
Which is why it's simple to implement and also simple conceptually. In
fact, shared_ptr could be expressed as simply a special case of unique_ptr.
Why does it surprise you that I might want to deal with any unique_ptr,
regardless of if it is a special case or not?
How? To do what with it?
Using unique_ptr<T, function<void(T*)>>, so that you don't have to force an
ownership scheme on to your interface's client, something which is both
very common and currently, quite irritating. Is not being more generic and
more flexible enough for you?
--
------=_Part_1318_12295923.1356010760244
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<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;">A shared_ptr is also "the unique owner of one =
strong reference".</blockquote><div><br></div><div>Which is why it's simple=
to implement and also simple conceptually. In fact, shared_ptr could be ex=
pressed as simply a special case of unique_ptr. Why does it surprise you th=
at I might want to deal with any unique_ptr, regardless of if it is a speci=
al case or not?</div><div><br></div><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;">How? To do=
what with it? </blockquote><div><br></div><div>Using unique_ptr<T,=
function<void(T*)>>, so that you don't have to force an ownership=
scheme on to your interface's client, something which is both very common =
and currently, quite irritating. Is not being more generic and more flexibl=
e enough for you?</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1318_12295923.1356010760244--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 20 Dec 2012 15:40:49 +0200
Raw View
On 20 December 2012 15:39, DeadMG <wolfeinstein@gmail.com> wrote:
> Using unique_ptr<T, function<void(T*)>>, so that you don't have to force an
> ownership scheme on to your interface's client, something which is both very
> common and currently, quite irritating. Is not being more generic and more
> flexible enough for you?
unique_ptr attempts to force a _stricter_ ownership scheme than
shared_ptr. Again,
write a custom deleter and use that with unique_ptr, I fail to see why
we should standardize
such a custom deleter.
--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Thu, 20 Dec 2012 06:03:08 -0800 (PST)
Raw View
------=_Part_1460_13478149.1356012188410
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Op woensdag 19 december 2012 12:01:02 UTC+1 schreef Daniel Kr=FCgler het=20
volgende:
> Please take a look at=20
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#1031=20
>
> If you have answers to the questions asked then I suggest to create=20
> a proposal paper. Ensure that you reference LWG issue 1031 and expect=20
> that people will ask critical questions in regard to invariants and=20
> implement-ability.=20
>
I think this request is somewhat different. The request is not to transfer=
=20
ownership to unique_ptr, but for unique_ptr to hold a (one) reference to=20
the shared object.
struct C
{
C(P&& p) : p_(p) { }
private:
P p_;
}
What should P be here? If it's unique_ptr, I can't store a shared_ptr. If=
=20
it's a shared_ptr, I can't store a raw or unique_ptr without overhead=20
(control block alloc).
Just using shared_ptr as much as possible avoids the issue but might not=20
always be possible.
--=20
------=_Part_1460_13478149.1356012188410
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Op woensdag 19 december 2012 12:01:02 UTC+1 schreef Daniel Kr=FCgler het vo=
lgende:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Please take a look =
at
<br>
<br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#=
1031" target=3D"_blank">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/lw=
g-closed.<wbr>html#1031</a>
<br>
<br>If you have answers to the questions asked then I suggest to create
<br>a proposal paper. Ensure that you reference LWG issue 1031 and expect
<br>that people will ask critical questions in regard to invariants and
<br>implement-ability.
<br></blockquote><div><br></div><div> I think this request is somewhat=
different. The request is not to transfer ownership to unique_ptr, but for=
unique_ptr to hold a (one) reference to the shared object.</div><div><br><=
/div><div>struct C</div><div>{</div><div> C(P&& p) : p_(p) { =
}</div><div>private:</div><div> P p_;</div><div>}</div><div><br></div=
><div>What should P be here? If it's unique_ptr, I can't store a shared_ptr=
.. If it's a shared_ptr, I can't store a raw or unique_ptr without overhead =
(control block alloc).<br></div><div><br></div><div>Just using shared_ptr a=
s much as possible avoids the issue but might not always be possible.</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1460_13478149.1356012188410--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 20 Dec 2012 16:07:04 +0200
Raw View
On 20 December 2012 16:03, Olaf van der Spek <olafvdspek@gmail.com> wrote:
> I think this request is somewhat different. The request is not to transfer
> ownership to unique_ptr, but for unique_ptr to hold a (one) reference to the
> shared object.
> struct C
> {
> C(P&& p) : p_(p) { }
> private:
> P p_;
> }
> What should P be here? If it's unique_ptr, I can't store a shared_ptr. If
> it's a shared_ptr, I can't store a raw or unique_ptr without overhead
> (control block alloc).
> Just using shared_ptr as much as possible avoids the issue but might not
> always be possible.
If you make that
C(P&& p) : p_(move(p)) {}
it should work when p_ is a shared_ptr, since you can move-construct a
shared_ptr
and you can also move-construct a shared_ptr from a unique_ptr.
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 20 Dec 2012 06:22:38 -0800 (PST)
Raw View
------=_Part_140_6592815.1356013358083
Content-Type: text/plain; charset=ISO-8859-1
It could work, but forces reference counting, which is not ideal if I only
need unique semantics on the result.
--
------=_Part_140_6592815.1356013358083
Content-Type: text/html; charset=ISO-8859-1
It could work, but forces reference counting, which is not ideal if I only need unique semantics on the result.
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_140_6592815.1356013358083--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 20 Dec 2012 16:24:58 +0200
Raw View
On 20 December 2012 16:22, DeadMG <wolfeinstein@gmail.com> wrote:
> It could work, but forces reference counting, which is not ideal if I only
> need unique semantics on the result.
For such optimized custom cases, you can specialize that C, or create a wrapper
that can take shared_ptr or unique_ptr. The case for supporting shared->unique
conversions in the standard doesn't thus far seem very convincing.
--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Thu, 20 Dec 2012 15:26:32 +0100
Raw View
On Thu, Dec 20, 2012 at 3:24 PM, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> For such optimized custom cases,
What happened to "You don't pay for what you don't use?"
This isn't some rare use case, in fact I think it's quite a common use case.
--
Olaf
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 20 Dec 2012 06:26:35 -0800 (PST)
Raw View
------=_Part_1485_896577.1356013595983
Content-Type: text/plain; charset=ISO-8859-1
Creating the wrapper would require the above functionality. Also,
specializing C won't always work- for example, if I intend to ship
precompiled code.
--
------=_Part_1485_896577.1356013595983
Content-Type: text/html; charset=ISO-8859-1
Creating the wrapper would require the above functionality. Also, specializing C won't always work- for example, if I intend to ship precompiled code.
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1485_896577.1356013595983--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Thu, 20 Dec 2012 15:29:41 +0100
Raw View
2012/12/20 Olaf van der Spek <olafvdspek@gmail.com>:
> Op woensdag 19 december 2012 12:01:02 UTC+1 schreef Daniel Kr=FCgler het
> volgende:
>
>> Please take a look at
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#1031
>>
>> If you have answers to the questions asked then I suggest to create
>> a proposal paper. Ensure that you reference LWG issue 1031 and expect
>> that people will ask critical questions in regard to invariants and
>> implement-ability.
>
>
> I think this request is somewhat different. The request is not to transf=
er
> ownership to unique_ptr, but for unique_ptr to hold a (one) reference to =
the
> shared object.
Yes, the requester has made his point clear after I presented the
issue and the question,
but this is not the only possible interpretation (see my quoted
issue). To the contrary
I would assume that any implicit conversion from shared_ptr to unique_ptr w=
ould
*transfer* ownership, because that is the main intention of unique_ptr
and the reason
for naming it that way.
It is just the fact that the generic deleter support and the generic
pointer support of
unique_ptr can be used to support very different models. Nonetheless I
consider such
models as very special. There is no reason that the standard library
should support
such special scenarios *directly*.
> struct C
> {
> C(P&& p) : p_(p) { }
> private:
> P p_;
> }
>
> What should P be here? If it's unique_ptr, I can't store a shared_ptr. If
> it's a shared_ptr, I can't store a raw or unique_ptr without overhead
> (control block alloc).
>
> Just using shared_ptr as much as possible avoids the issue but might not
> always be possible.
I don't find the example compelling enough to standardize a conversion from
any shared_ptr to unique_ptr. It would give a false impression what
the responsibility
of the pointee would be.
The current design already allows anyone to implement the request very easi=
ly,
like so:
#include <memory>
template<class T>
struct pseudo_deleter {
typedef std::shared_ptr<T> pointer;
void operator()(pointer) const {}
};
template<class T>
using funny_ptr =3D std::unique_ptr<T, pseudo_deleter<T>>;
int main()
{
std::shared_ptr<int> pi(new int(12));
funny_ptr<int> pf(pi);
}
I don't think that this is worth standardizing this: The request would have=
the
effect that code that was unintentionally written would compile and would
possible do different things as expected. This is different, if a user
explicitly
provides std::unique_ptr<T, pseudo_deleter<T>> to those who are interested
in such conversion (Add to the list a factory function template, if
you prefer). If this
conversion support result in funny programs they can complain to the invent=
or
of funny_ptr.
- Daniel
--=20
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 20 Dec 2012 16:30:13 +0200
Raw View
On 20 December 2012 16:26, Olaf van der Spek <olafvdspek@gmail.com> wrote:
> On Thu, Dec 20, 2012 at 3:24 PM, Ville Voutilainen
> <ville.voutilainen@gmail.com> wrote:
>> For such optimized custom cases,
> What happened to "You don't pay for what you don't use?"
> This isn't some rare use case, in fact I think it's quite a common use case.
Then by all means substantiate your claims - if it's common, you have
better grounds
for standardizing it. And, if you have a
unique_ptr-wrapping-a-shared-block, you are
paying for the shared_ptr cost, there's no optimization in having that
unique_ptr there.
--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 20 Dec 2012 06:42:51 -0800 (PST)
Raw View
------=_Part_339_13985575.1356014571928
Content-Type: text/plain; charset=ISO-8859-1
Particularly, recently I was using the Clang API. They have a nasty habit
of using something similar to this, except without any security or safety
whatsoever- passing booleans to indicate ownership. In addition, if Clang
owns an object that you have created, then it will always delete that
object, making it impossible to use any custom allocators. And there is no
way in hell that they could convert half their codebase to be templated on
pointer types.
There is no reason that the standard library
> should support
> such special scenarios *directly*.
The user-defined equivalents are not as efficient as a Standardised
variant. Your class showing an alteration of the unique_pointer using the
deleter typedef is not possible to use as a run-time abstraction. If a
template would be sufficient, then I could simply template on the pointer
type directly.
--
------=_Part_339_13985575.1356014571928
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Particularly, recently I was using the Clang API. They have a nasty habit o=
f using something similar to this, except without any security or safety wh=
atsoever- passing booleans to indicate ownership. In addition, if Clang own=
s an object that you have created, then it will always delete that object, =
making it impossible to use any custom allocators. And there is no way in h=
ell that they could convert half their codebase to be templated on pointer =
types.<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px=
0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 20=
4); border-left-style: solid; padding-left: 1ex;"> There is no reason =
that the standard library <br>should support <br>such special sce=
narios *directly*. </blockquote><div><br></div><div>The user-defined e=
quivalents are not as efficient as a Standardised variant. Your class showi=
ng an alteration of the unique_pointer using the deleter typedef is not pos=
sible to use as a run-time abstraction. If a template would be sufficient, =
then I could simply template on the pointer type directly.</div><div><br></=
div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_339_13985575.1356014571928--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Thu, 20 Dec 2012 15:58:26 +0100
Raw View
2012/12/20 DeadMG <wolfeinstein@gmail.com>:
> Particularly, recently I was using the Clang API. They have a nasty habit of
> using something similar to this, except without any security or safety
> whatsoever- passing booleans to indicate ownership. In addition, if Clang
> owns an object that you have created, then it will always delete that
> object, making it impossible to use any custom allocators. And there is no
> way in hell that they could convert half their codebase to be templated on
> pointer types.
I don't know the Clang API, so I cannot properly respond whether it
makes sense to compare it with an std::shared_ptr to std::unique_ptr
conversion.
>> There is no reason that the standard library
>> should support
>> such special scenarios *directly*.
>
>
> The user-defined equivalents are not as efficient as a Standardised variant.
Sorry, I cannot accept this argument alone, because this can be
brought for *anything* that is not yet part of the library.
> Your class showing an alteration of the unique_pointer using the deleter
> typedef is not possible to use as a run-time abstraction. If a template
> would be sufficient, then I could simply template on the pointer type
> directly.
Your initial request was quite nebulous to me (and it still is),
therefore I brought the example of an existing issue. I constructed
funny_ptr from my *understanding* what you want to have supported. Now
you claim that I'm not properly modeling your intention. I can accept
that, so I'm giving this here my recommendation to you:
Please write up a concrete proposal that makes *clear* what you think
should be supported and what you *think* you want to impose on
implementations to realize that and what your think what kind of
problems they solve. Remember that your *idea* somewhere in your mind
alone will not be sufficient to ensure that any future implementation
would realize what you *thought* they should. Wording needs to be
added that realizes this. A reference implementation is not required
but I think would be helpful, because at least I have not finally
understood your full *requirements* are.
Given these requirements I would still like to see what impact this
request would have on possible std::unique_ptr implementations.
- Daniel
--
.
Author: Sebastian Gesemann <s.gesemann@gmail.com>
Date: Thu, 20 Dec 2012 16:20:43 +0100
Raw View
On Thu, Dec 20, 2012 at 2:39 PM, DeadMG <wolfeinstein@gmail.com> wrote:
> Sebastian wrote:
>> DeadMG wrote:
>>> And the principle benefit is that it would now be possible
>>> to write a function that takes any kind of pointer at run-time.
>> How? To do what with it?
> Using unique_ptr<T, function<void(T*)>>, so that you don't have to force an
> ownership scheme on to your interface's client, something which is both very
> common and currently, quite irritating. Is not being more generic and more
> flexible enough for you?
I have two problems with this:
(1) If this thing is more general and allowed shared ownership as well
it should not have the name "unique_ptr". The meaning of
unique_ptr<T,...> is "unique owner of a T" and not "unique owner of
something else that is somehow related to some T whose ownership is
possibly shared".
(2) I fail to imagine use cases for a more general
"uncertain-ownership-at-compile-time-and-move-only" smart pointer.
What are these use cases?
--
.
Author: Paul Smith <pl.smith.mail@gmail.com>
Date: Thu, 20 Dec 2012 07:25:33 -0800 (PST)
Raw View
------=_Part_79_24682588.1356017133443
Content-Type: text/plain; charset=ISO-8859-1
On Wednesday, December 19, 2012 12:41:41 PM UTC+2, DeadMG wrote:
>
> One of the things that annoys me about the Standard ownership classes is
> that you have to choose which one you want ahead of time. Sometimes this is
> fine, but sometimes it's rather annoying.
>
> So I propose std::unique_ptr<T, std::function<void(T*)>>.
>
> Principally, I believe this already functions for most cases. The primary
> issue is that shared_ptr cannot convert. I suggest that shared_ptr have an
> explicit conversion (operator?) to unique_ptr<T, implementation-defined>,
> where the deleter manages the reference count. This way, unique_ptrs with
> type-erased or templated deleters can represent any ownership scheme.
>
>
A general note: I think you managed to confuse pretty much everyone
(including me) with your exposition. When you make a proposal, don't
assume that everyone knows what you're talking about - be more elaborate.
A use case, preferably a small piece of code that demonstrates the issue and
your proposed solution, is always a good idea.
That being said, I think I managed to understand what you're aiming at (I
might be wrong, though.)
You're basically looking for a type-erased smart-pointer. Why you decided
to use 'unique_ptr' for this task is beyond me. A 'unique_ptr' is just what
it's
name says: the unique owner of *the object it points to* - not of a
reference
to the object or whatnot. It's just not what it's for.
You're looking for some kind of 'any_ptr<T>': something that can be used to
store
a dumb pointer, but also a 'shared_ptr' or (perhaps) anything that behaves
like a pointer.
I doubt that it can be safely used to store a 'unique_ptr', though, as the
uniqueness
of the ownership is mandated by the non-copyability of 'unique_ptr', which
is lost
when the type is erased.
I find the general usefulness of this somewhat questionable. Once again, I
suggest that
you present a real use case. You might also be interested in the
recently-accepted
Boost.TypeErasure library, that can be used to implement something like
this, although it's
scope is much broader (and might be more expensive than a specilizaed class
in
this case. I'm not familiar enough with the library to tell.)
--
Paul Smith
--
------=_Part_79_24682588.1356017133443
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br>On Wednesday, December 19, 2012 12:41:41 PM UTC+2, DeadMG wrote:<blockq=
uote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-col=
or: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;" =
class=3D"gmail_quote">One of the things that annoys me about the Standard o=
wnership classes is that you have to choose which one you want ahead of tim=
e. Sometimes this is fine, but sometimes it's rather annoying.<div><br></di=
v><div>So I propose std::unique_ptr<T, std::function<void(T*)>>=
..</div><div><br></div><div>Principally, I believe this already functions fo=
r most cases. The primary issue is that shared_ptr cannot convert. I sugges=
t that shared_ptr have an explicit conversion (operator?) to unique_ptr<=
T, implementation-defined>, where the deleter manages the reference coun=
t. This way, unique_ptrs with type-erased or templated deleters can represe=
nt any ownership scheme.</div><div> </div></blockquote><div> </di=
v><div><div>A general note: I think you managed to confuse pretty much ever=
yone</div><div>(including me) with your exposition. When you make a proposa=
l, don't</div><div>assume that everyone knows what you're talking about - b=
e more elaborate.</div><div>A use case, preferably a small piece of code th=
at demonstrates the issue and</div><div>your proposed solution, is always a=
good idea.</div><div> </div><div>That being said, I think I managed to und=
erstand what you're aiming at (I might be wrong, though.)</div><div>You're =
basically looking for a type-erased smart-pointer. Why you decided</div><di=
v>to use 'unique_ptr' for this task is beyond me. A 'unique_ptr' is just wh=
at it's</div><div>name says: the unique owner of *the object it points to* =
- not of a reference</div><div>to the object or whatnot. It's just not what=
it's for.</div><div> </div><div>You're looking for some kind of 'any_ptr&l=
t;T>': something that can be used to store</div><div>a dumb pointer, but=
also a 'shared_ptr' or (perhaps) anything that behaves like a pointer=
..</div><div>I doubt that it can be safely used to store a 'unique_ptr', tho=
ugh, as the uniqueness</div><div>of the ownership is mandated by the non-co=
pyability of 'unique_ptr', which is lost</div><div>when the type is erased.=
</div><div> </div><div>I find the general usefulness of this somewhat quest=
ionable. Once again, I suggest that</div><div>you present a real use case. =
You might also be interested in the recently-accepted</div><div>Boost.TypeE=
rasure library, that can be used to implement something like this, although=
it's</div><div>scope is much broader (and might be more expensive than a s=
pecilizaed class in</div><div>this case. I'm not familiar enough with the l=
ibrary to tell.)</div><div> </div><div>--</div><div>Paul Smith</div> <=
/div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_79_24682588.1356017133443--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 20 Dec 2012 09:24:47 -0600
Raw View
--0015175d0782ef97a604d14a6f6f
Content-Type: text/plain; charset=ISO-8859-1
On 20 December 2012 08:42, DeadMG <wolfeinstein@gmail.com> wrote:
> There is no reason that the standard library
>> should support
>> such special scenarios *directly*.
>
>
> The user-defined equivalents are not as efficient as a Standardised
> variant.
>
Please substantiate this claim. Are you saying that your proposal requires
a magic type that has special compiler support?
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
--0015175d0782ef97a604d14a6f6f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On 20 December 2012 08:42, DeadMG <span dir=3D"ltr"><<a href=3D"mailto:w=
olfeinstein@gmail.com" target=3D"_blank">wolfeinstein@gmail.com</a>></sp=
an> wrote:<br><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 class=3D"im"><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">=A0There is no reason that the standard =
library=A0<br>
should support=A0<br>such special scenarios *directly*.=A0</blockquote><div=
><br></div></div><div>The user-defined equivalents are not as efficient as =
a Standardised variant. </div></blockquote><div><br></div><div>Please subst=
antiate this claim. =A0Are you saying that your proposal requires a magic t=
ype that has special compiler support?</div>
</div>-- <br>=A0Nevin ":-)" Liber=A0 <mailto:<a href=3D"mailto=
:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>>=
=A0 (847) 691-1404
<p></p>
-- <br />
<br />
<br />
<br />
--0015175d0782ef97a604d14a6f6f--
.
Author: Sebastian Gesemann <s.gesemann@gmail.com>
Date: Thu, 20 Dec 2012 16:32:29 +0100
Raw View
On Thu, Dec 20, 2012 at 2:39 PM, DeadMG wrote:
> > [...]
> Using unique_ptr<T, function<void(T*)>>, so that you don't have to force an
> ownership scheme on to your interface's client, something which is both very
> common and currently, quite irritating. Is not being more generic and more
> flexible enough for you?
Two issues:
(1) I think your idea to (mis)use "unique_ptr" for something that is
actually more like an "uncertain_ptr" (uncertain with respect to
ownership at compile-time) is a bad idea. unique_ptr<T,...> means
"unique ownership of a T" and not "unique ownership of something else
entirely that is somhow linked to a T object could possibly be
shared".
(2) I have trouble imagining use cases for this. That's why I asked
about how you would use such a thing.
--
.
Author: Sebastian Gesemann <s.gesemann@gmail.com>
Date: Thu, 20 Dec 2012 16:39:15 +0100
Raw View
On Thu, Dec 20, 2012 at 4:24 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
> On 20 December 2012 08:42, DeadMG <wolfeinstein@gmail.com> wrote:
>>>
>>> There is no reason that the standard library
>>> should support
>>> such special scenarios *directly*.
>>
>> The user-defined equivalents are not as efficient as a Standardised
>> variant.
>
> Please substantiate this claim. Are you saying that your proposal requires
> a magic type that has special compiler support?
I can actually answer this. The inner workings of a shared_ptr (how it
manages the reference counts and deleters) are implementation details.
An "uncertain_ptr" (*) could quite possibly exploit this knowledge and
avoid extra book keeping and/or allocations that would otherwise be
necessary.
(* uncertain ownerchip at compile-time with keep-alive functionality
when converted from unique_ptr or shared_ptr)
--
.
Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Thu, 20 Dec 2012 22:27:25 -0300
Raw View
On Thu, Dec 20, 2012 at 12:39 PM, Sebastian Gesemann
<s.gesemann@gmail.com> wrote:
> On Thu, Dec 20, 2012 at 4:24 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
>> On 20 December 2012 08:42, DeadMG <wolfeinstein@gmail.com> wrote:
>>>>
>>>> There is no reason that the standard library
>>>> should support
>>>> such special scenarios *directly*.
>>>
>>> The user-defined equivalents are not as efficient as a Standardised
>>> variant.
>>
>> Please substantiate this claim. Are you saying that your proposal requires
>> a magic type that has special compiler support?
>
> I can actually answer this. The inner workings of a shared_ptr (how it
> manages the reference counts and deleters) are implementation details.
> An "uncertain_ptr" (*) could quite possibly exploit this knowledge and
> avoid extra book keeping and/or allocations that would otherwise be
> necessary.
>
Like pretty much everyone else here I have no idea what the requester
wants and even less why he choose unique_ptr for that. But like you I
did grasp that it has something to do with recycling and perhaps
adapting the mechanism that shared_ptr uses to control ownership.
So, it's seems that he wants some sort of most basic smart_ptr, one
that would serve as a basis for the others.
It reminds me of the good old policy-based smart pointers from
Alexandrescu. But then I recall when that form of design did not make
it into Boost (and I was among the ones that preferred the simpler
shared_ptr).
Being able to change the ownership strategy as you copy or move
objects along might be a reasonable requirement. Specially if the
change is in the right direction (like from uniquely owned to shared)
Unfortunately, that's a far as the vague idea goes in my head. I can't
think of anything more concrete, so, I'm left with the feeling that he
is on to something valid, but can't quite get it.
--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com
--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 20 Dec 2012 14:10:46 +0200
Raw View
On 20 December 2012 13:39, DeadMG <wolfeinstein@gmail.com> wrote:
> It retains sole ownership of an object- the strong reference.
So, what you want is a freedom to get _some_ kind of a unique_ptr from
a shared_ptr, in order
to be able to cope with unfortunate design decisions in module X, to
express different semantics
in module Y. So far, in general, I support such wishes.
But now there's a snag: I assume you need unique_ptr<T,
strongref_deleter>? If you can control
that module Y uses such a type, wouldn't you also be able to control
that it just uses a shared_ptr?
In other words, while the idea of expressing different semantics is
sometimes sound, I fail to
see what problem we're practically solving here, and why you couldn't
just use shared_ptr in
module Y. Is it intended to just prevent copying (but allow moving) of
the handle-to-T in module Y?
Can't you just write a custom deleter that is constructible from a
shared_ptr, and use a unique_ptr
with such a deleter?
--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 20 Dec 2012 16:32:22 +0200
Raw View
On 20 December 2012 16:26, DeadMG <wolfeinstein@gmail.com> wrote:
> Creating the wrapper would require the above functionality. Also,
> specializing C won't always work- for example, if I intend to ship
> precompiled code.
Creating the wrapper does not require standard support for direct conversion
from shared_ptr to unique_ptr.
--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 20 Dec 2012 10:47:29 -0500
Raw View
On Thu, Dec 20, 2012 at 10:25 AM, Paul Smith <pl.smith.mail@gmail.com> wrote:
>
> On Wednesday, December 19, 2012 12:41:41 PM UTC+2, DeadMG wrote:
>>
>> One of the things that annoys me about the Standard ownership classes is
>> that you have to choose which one you want ahead of time. Sometimes this is
>> fine, but sometimes it's rather annoying.
>>
>> So I propose std::unique_ptr<T, std::function<void(T*)>>.
>>
>> Principally, I believe this already functions for most cases. The primary
>> issue is that shared_ptr cannot convert. I suggest that shared_ptr have an
>> explicit conversion (operator?) to unique_ptr<T, implementation-defined>,
>> where the deleter manages the reference count. This way, unique_ptrs with
>> type-erased or templated deleters can represent any ownership scheme.
>>
>
>
> A general note: I think you managed to confuse pretty much everyone
> (including me) with your exposition. When you make a proposal, don't
> assume that everyone knows what you're talking about - be more elaborate.
> A use case, preferably a small piece of code that demonstrates the issue and
> your proposed solution, is always a good idea.
> That being said, I think I managed to understand what you're aiming at (I
> might be wrong, though.)
> You're basically looking for a type-erased smart-pointer. Why you decided
> to use 'unique_ptr' for this task is beyond me. A 'unique_ptr' is just what
> it's
> name says: the unique owner of *the object it points to* - not of a
> reference
> to the object or whatnot. It's just not what it's for.
> You're looking for some kind of 'any_ptr<T>': something that can be used to
> store
> a dumb pointer, but also a 'shared_ptr' or (perhaps) anything that behaves
> like a pointer.
> I doubt that it can be safely used to store a 'unique_ptr', though, as the
> uniqueness
> of the ownership is mandated by the non-copyability of 'unique_ptr', which
> is lost
> when the type is erased.
> I find the general usefulness of this somewhat questionable. Once again, I
> suggest that
> you present a real use case. You might also be interested in the
> recently-accepted
> Boost.TypeErasure library, that can be used to implement something like
> this, although it's
> scope is much broader (and might be more expensive than a specilizaed class
> in
> this case. I'm not familiar enough with the library to tell.)
> --
> Paul Smith
>
>
FWIW, this is my interpretation as well.
I do see some usefulness. At least for a function that just uses the
pointer and doesn't keep it beyond the function call. Should that
function instead take the raw pointer? (Maybe, but I think many
people are trying to avoid raw pointers completely, and the conversion
to raw pointer is ugly.) Or does that function need to be templatized
just so it can use whatever pointer type the client has? Neither
option seems great. Converting to a type-erased pointer makes some
sense.
Now _keeping_ that any_ptr<T> around inside a struct becomes scary.
Or copying it. How does that work with a unique_ptr? Or do the
copy-semantics need to be runtime as well? Call ptr.clone() which
does move for unique_ptr but ref++ for shared_ptr????
Tony
--
.
Author: Mateusz Loskot <mateusz@loskot.net>
Date: Thu, 20 Dec 2012 11:41:15 +0000
Raw View
On 20 December 2012 11:39, DeadMG <wolfeinstein@gmail.com> wrote:
> It retains sole ownership of an object- the strong reference.
I refer to resource ownership and the statement from your post:
"does not own the resource that the shared_ptr owns"
Best regards,
--
Mateusz Loskot, http://mateusz.loskot.net
--
.
Author: Marshall Clow <mclow.lists@gmail.com>
Date: Fri, 21 Dec 2012 19:15:34 -0800
Raw View
On Dec 20, 2012, at 7:47 AM, Tony V E <tvaneerd@gmail.com> wrote:
> FWIW, this is my interpretation as well.
>
> I do see some usefulness. At least for a function that just uses the
> pointer and doesn't keep it beyond the function call. Should that
> function instead take the raw pointer? (Maybe, but I think many
> people are trying to avoid raw pointers completely, and the conversion
> to raw pointer is ugly.)
I call that "a reference" unless it is optional, in which case a pointer is the best choice.
-- Marshall
Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>
A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
-- Yu Suzuki
--
.