Boost logo

Boost :

From: Kevin Spinar (spinarkm_at_[hidden])
Date: 2006-07-09 00:43:25


On 7/8/06, Matt Calabrese <rivorus_at_[hidden]> wrote:
> Glad to see it's coming along!
>
> Another couple of suggestions -- it would be nice if the clone_ptr took
> a clone allocator as a policy (
> http://boost.org/libs/ptr_container/doc/reference.html#the-clone-allocator-concept),

clone_ptr accepts a clone allocator as a parameter to the constructor:
template<class Y, class Alloc> clone_ptr(Y * p, Alloc);
My apologies that it was not more clear. However, it seems I am
bending the requirements of a clone allocator by performing default
and copy construction.

> and as well, I would personally like to see the clone-on-copy vs
> clone-on-write implementation able to be toggled through a
> template argument if it's not too much trouble, since clone-on-copy still
> has the advantages of smaller size, more deterministic performance, and
> perhaps most importantly, more predictable exceptions.

The problem is, I don't see that it is feasible to write a
clone-on-copy implementation that is compatible with assocative
containers. To be usable with assocative containers, a clone_ptr must
exhibit the following behavior:

clone_ptr<base> p(new derived);
clone_ptr<base> p2(p); // assertion: p and p2 are equal (p < p2 ==
false && p2 < p == false)
p2->modify_object(); // assertion: p and p2 are no longer equal

If the first assertion was not true, then copy construction of
assocative containers would fail: the clone_ptrs in the container
would not maintain their relative sort order after being copied.

If the second assertion was not true, then you would be unable to
write code resembling the following:

clone_ptr<base> p = *myset.begin();
p->modify_object();
myset.insert(p); // insert fails--object already exists in the set

> An explicit
> "separate" member function would also be nice, which would explicitly
> clone the object
> if it currently has shared ownership. The main purpose of this would be to
> get around the fact that non-const -> and * may throw an exception if the
> object isn't yet cloned -- this way, you may clone the object explicitly
> prior to doing other unrelated operations which otherwise would have a
> no-throw guarantee, potentially saving the programmer from having to
> explicitly try and catch or have to unintuitively call non-const get prior
> to performing other operations in order to implicitly remove the possibility
> of exceptions being thrown later on in code.

Thank you, I'll plan to add it.

> Finally, I like the fact that you are propogating the constness to the
> stored object, however, since that is the path you are taking, I don't
> think that clone_ptr is a proper name. Traditionally, a pointer merely
> references the object and its constness doesn't affect the target, and as
> well, you don't normally expect copying of the target when copying something
> that merely references the target. In fact, with the way it is
> now, I'd argue that the * and -> operators are only used because there is no
> way to directly forward the interface of the
> object, not because you are implementing a pointer concept (i.e. they're
> only used because you can't overload the . operator), so I wouldn't really
> call it a smart pointer at all. As you said in documentation, it's really
> more like an object wrapper than a smart pointer. Because of this, perhaps
> "smart_object" or "dynamic_object" or something along those lines would be a
> more accurate name than "clone_ptr." Really,
> the pointer aspect is more of an implementation detail than it is a logical
> part of the concept.

Indeed. Perhaps poly_object?

Kevin Spinar


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk