Implicitly converting HeldTypes from Derived to Base?
I have a situation like this: // foo.cpp #include <boost/intrusive_ptr.hpp> #include <boost/python.hpp> using namespace boost; using namespace boost::python; class RefCounted { public: RefCounted() { _count = 0; } virtual ~RefCounted() { } int _count; }; void intrusive_ptr_add_ref(RefCounted* ptr) { ++(ptr->_count); } void intrusive_ptr_release(RefCounted* ptr) { if (--(ptr->_count) == 0) { delete ptr; } } class A : public RefCounted { }; class B : public A { }; typedef intrusive_ptr<A> APtr; typedef intrusive_ptr<B> BPtr; void foo(APtr a) { } BOOST_PYTHON_MODULE(foo) { class_<A, APtr>("A"); class_<B, BPtr, bases<A> >("B"); def("foo", &foo); // Without implicitly_convertible, foo(B()) fails with: // // Traceback (most recent call last): // File "<stdin>", line 1, in ? // Boost.Python.ArgumentError: Python argument types in // foo.foo(B) // did not match C++ signature: // foo(boost::intrusive_ptr<A>) implicitly_convertible<BPtr, APtr>(); } Is there any way that implicitly_convertible call from the Derived HeldType to the Base HeldType can be made automatic? Thanks, Chad
Chad Austin <caustin@gmail.com> writes:
I have a situation like this:
BOOST_PYTHON_MODULE(foo) { class_<A, APtr>("A"); class_<B, BPtr, bases<A> >("B"); def("foo", &foo);
// Without implicitly_convertible, foo(B()) fails with: // // Traceback (most recent call last): // File "<stdin>", line 1, in ? // Boost.Python.ArgumentError: Python argument types in // foo.foo(B) // did not match C++ signature: // foo(boost::intrusive_ptr<A>) implicitly_convertible<BPtr, APtr>(); }
Is there any way that implicitly_convertible call from the Derived HeldType to the Base HeldType can be made automatic?
Not in general. By the time class_<B, BPtr, bases<A> >("B"); is uttered, there's no *compile-time* information linking APtr with A, so there's no way to test for is_convertible<BPtr,APtr> ... and you need to test that before you utter implicitly_convertible<BPtr,APtr>(). Actually, without knowing about APtr, you can't even say implicitly_convertible<BPtr,APtr>(). One possibility would be to extend Boost.Python to allow: class_<A, APtr>("A"); class_<B, BPtr, bases<APtr> >("B"); ^^^^ That would be a kind of shorthand. Another possibility would be to use partial specialization with template template parameters to deduce that BPtr is actually SomeTemplate<B>, and check for implicit convertibility from SomeTemplate<B> to SomeTemplate<A>, and if that succeeds, then you can utter implicitly_convertible<SomeTemplate<B>,SomeTemplate<A> >(). That would rely on the HeldTypes both being specializations of the same template (admittedly likely) and on the compiler supporting both aforementioned features. The last approach is for all intents and purposes automatic. It's also a fair amount of work to implement. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (2)
-
Chad Austin -
David Abrahams