[C++-sig] Re: Less than transparent proxies

Raoul Gough RaoulGough at yahoo.co.uk
Tue Apr 15 21:10:37 CEST 2003

"Dave Abrahams" <dave at boost-consulting.com> wrote in message
news:000801c30363$31948b10$9101a8c0 at penguin...
> Raoul Gough wrote:
> > I've thought of various ways of trying to work the proxies into
> > Python. Obviously Python doesn't have an indirection operator->(),
> > which is how this is often done in C++ (i.e. client code has to
> > about the proxy object, and uses operator->() when accessing
> > of the referant). One option might be to try and set up some kind
> > IS-A relationship between the Python types (referant IS-A proxy),
> > I'm starting to think the cleanest option would be to provide a
> > __cxxholder__ method so that client code can explicitly access the
> > holder/proxy when necessary.
> >
> > e.g.
> >
> > obj = HeldViaProxyType()
> > if obj.__cxxholder__().unique():
> >     # ...
> Normally proxies in Python don't give you a way to distinguish the
> from the target class.

So the C++ style of proxies doesn't fit Python. I guess I was trying
to transfer the concepts directly, but there's no actual need for

> > Unfortunately, I seem to have hit a serious problem right away.
> > test code (below) produces "already has a registered
> > to_python_converter" at load time, when defining the shared_ptr
> > which is already registered as a holder for the referant. I guess
> > was inevitable. Any suggestions or interest in the idea?
> It's interesting, but I don't think you've got the best approach
here.  Why
> the cumbersome extra syntax? Why the redundant exception-handling
code in
> your module initialization function?

Don't really remember why the exception handler is there - unless it
was necessary with the earlier version of the library (I converted all
my boost C++ Python code a while back).

> And why not just:
> ----8<---- code starts ----8<----
> #include <iostream>
> #include <ostream>
> #include <boost/python.hpp>
> #include <boost/shared_ptr.hpp>
> struct Hello {
>   Hello () {
>     std::cout << "Hello::Hello\n";
>   }
>   ~Hello () {
>     std::cout << "Hello::~Hello\n";
>   }
>   void hello () { std::cout << "hello\n"; }
> };
> {
>   using namespace boost::python;
>       class_<Hello, boost::shared_ptr<Hello> >("Hello")
>         .def ("hello", &Hello::hello)
>         .def ("_unique", &boost::shared_ptr<Hello>::unique)
>         ;
> }

I'm surprised to learn that this works at all, so it's no wonder I
didn't think of doing it that way :-) I would have thought that the
Python object (e.g. "<proxy.Hello object at 0x00765730>") would not be
suitable for the call to shared_ptr::unique(). On the C++ side, an
object is _either_ a Hello or a shared_ptr<Hello>, and neither one of
them provides both functions (hello and unique). So does the Python
object get converted to the shared_ptr, rather than its target object,
depending on the type of the C++ function being applied?

Anyway, it looks like a nice and easy solution - thanks very much!

Raoul Gough
see http://home.clara.net/raoulgough/ for my work availability

More information about the Cplusplus-sig mailing list