[C++-sig] Re: keeping weak_ptrs upon python objects smart_ptrholders

Nicolas LELONG / mgdesign nlelong at mgdesign.org
Thu Nov 20 11:10:50 CET 2003

"David Abrahams" <dave at boost-consulting.com> writes :

> It's not a dummy, but it is conjured up "from thin air" using a custom
> deleter which just manages a reference to the containing Python
> object.  If you don't copy this into some other shared_ptr somewhere,
> it becomes the last one using that count after the call completes.

Yep, I think that's what I meant by 'dummy' ;)

> If you change the way A is wrapped so it's held by shared_ptr:
>    class_<A,boost::shared_ptr<ACallback>, boost::noncopyable>("A")
>        ...
>        ;
> and change:
>    setInstance(boost::shared_ptr<A> a) { instance = a; };
> to
>    setInstance(boost::shared_ptr<ACallback>& a) { instance = a; };
> *then* the weak pointer will be using the shared_ptr inside the
> Python object.

Aargh, I thought about this, and I would have bet I tried it ! it seems that
I made a mistake somewhere
as it works now you tell me !... I think I should not have removed the
explicit boost::shared_ptr<ACallback>
holder specification (I thought that was the 'default' holder when not
specified... I still have troubles
grabbing every aspects of BPL holding scheme - and not enough time to dive
into the doc/code...)

It even works with 'setInstance(boost::shared_ptr<ACallback> a)' which I
find more intuitive.

I still have another "problem" : not every subclass of A is a subclass of
ACallback (ie there are subclasses
implemented in C++) - for those, I stumbled upon a conversion problem.

So let's say I have the additional code :


struct D : A
  virtual std::string f() { return "D::f()"; }


class_<D, boost::shared_ptr<D>, bases<A>, boost::noncopyable>("D")
  .def("f", &D::f);

implicitly_convertible< boost::shared_ptr<D>, boost::shared_ptr<A> >();


with the following set of functions, I can have something working as I
expect :


void setInstance(boost::shared_ptr<A> a) { instance = a; };
void setInstance_wrapper(boost::shared_ptr<ACallback> a) {
setInstance(a); };
void setInstance_wrapper2(boost::shared_ptr<D> d) { setInstance(d); };


def("setInstance", setInstance);
def("setInstance", setInstance_wrapper);
def("setInstance", setInstance_wrapper2);


which seems to mean that I have to make a wrapper for every different holder
defined in the hierachy tree.
That's doable !

> I think it might be better to do more to make this
> work automatically, but I'm not sure just what that "more" would be.

hmm, of course, that would be great - I'm not used to the BPL internals so I
may tell some wrong/stupid thing:

wouldn't it be possible, when converting the arguments provided to a
function, that if :

- a shared_ptr (weak_ptr) argument is the 'target' of a specified implicit
conversion whose source is the type of
  the provided value for the argument

- AND the provided value wrapper is held by shared_ptr

- THEN the shared_ptr " conjured up 'from thin air' " is contructed from the
shared_ptr holding the provided value
  thus having a valid reference count

I don't if/where/how all this could be done, and if it covers every aspect
of the problem !
What do you think ?

Thans once more for your help :)

More information about the Cplusplus-sig mailing list