[C++-sig] Loss of polymorphism with std::auto_ptr

Roman Yakovenko roman.yakovenko at gmail.com
Wed Feb 14 20:54:19 CET 2007


On 2/14/07, Pertti Kellomäki <pk at cs.tut.fi> wrote:
> I've followed the recipe for transfering ownership at
> <http://www.boost.org/libs/python/doc/v2/faq.html#ownership>.
> Everything works nicely, except that I seem to lose polymorphism.
>
> Let's say I have a base class A and a derived class A1, and
> class B which has a member function set_a(A*). If I wrap
> B::set_a() using an auto_ptr as suggested in the FAQ, and try
> to call it from Python with an A1 object, I get the following
> error:
>
> Boost.Python.ArgumentError: Python argument types in
>      B.set_a(B, A1)
> did not match C++ signature:
>      set_a(B {lvalue}, std::auto_ptr<A>)
>
> I know how to fix this by creating another wrapper for set_a
> that takes std::auto_ptr<A1> and binding it to "set_a" in Python.
> However, I would like to avoid this if possible, since the
> number of wrappers can grow quite large.
>
> Any suggestions as to how to avoid the per subclass wrappers?
>
> I have attached a small but complete example.
> --
> Pertti
>
> #include <boost/python.hpp>
> class A {
> };
>
> class A1 : public A {
> };
>
> class B {
> public:
>   B();
>   void set_a(A* a);
>   A* a_;
> };
>
> B::B() { a_ = new A(); };
>
> void B::set_a(A* a) {
>   delete a_;
>   a_ = a;
> };
>
> void set_a(B& b, std::auto_ptr<A> a) {
>   b.set_a(a.get());
>   a.release();
> };
>
> using namespace boost::python;
>
> BOOST_PYTHON_MODULE(testing) {
>   class_<A, std::auto_ptr<A> >("A", init<>())
>     ;
>   class_<A1, bases< A >, std::auto_ptr<A1> >("A1", init<>())
>     ;
>   class_<B>("B", init<>())
>     .def("set_a", &set_a)
>     ;
> }
>
> /*
>   Running this in Python
>
> $ python2.4
> Python 2.4.4 (#3, Dec 21 2006, 12:46:16)
> [GCC 4.1.1] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
> >>> from testing import *
> >>> b = B()
> >>> b.set_a(A())
> >>> b.set_a(A1())
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> Boost.Python.ArgumentError: Python argument types in
>     B.set_a(B, A1)
> did not match C++ signature:
>     set_a(B {lvalue}, std::auto_ptr<A>)
> >>>
>
> */

Take a look on http://boost.org/libs/python/doc/v2/implicit.html#implicitly_convertible-spec

I think you need to register implicit conversion between auto_ptr<A1> and
auto_ptr<A>


-- 
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/



More information about the Cplusplus-sig mailing list