[C++-sig] Python-overridable method taking const ref?

Paul Melis pyplusplus at assumetheposition.nl
Wed Feb 4 20:26:16 CET 2009


Hi Roman,

Roman Yakovenko wrote:
> On Wed, Feb 4, 2009 at 8:49 PM, Paul Melis
> <pyplusplus at assumetheposition.nl> wrote:
>   
>> Classes with protected destructors (as found when custom reference
>> counting is used) seem to cause some trouble when using bp::wrapper<>
>> containing  a method that takes a const reference to a refcounted class.
>>
>> Say I have:
>>
>> #include <cstdio>
>> #include <boost/python.hpp>
>>
>> namespace bp = boost::python;
>>
>> class Thing
>> {
>> protected:
>>    virtual ~Thing() {}
>> };
>>
>> class Callback
>> {
>> public:
>>    Callback() { }
>>    virtual void execute(const Thing& t) { }
>> protected:
>>    virtual ~Callback() {}
>> };
>>
>> And I want to add a wrapper class so that Callback can be derived from
>> in Python and its execute() method overridden.
>>     
>
> Try the following code:
>
> #include "boost/python.hpp"
>
> namespace bp = boost::python;
>
> struct Callback_wrapper : Callback, bp::wrapper< Callback > {
>
>     Callback_wrapper( )
>     : Callback( )
>       , bp::wrapper< Callback >(){
>         // null constructor
>
>     }
>
>     virtual void execute( ::Thing const & t ) {
>         if( bp::override func_execute = this->get_override( "execute" ) )
>             func_execute( boost::ref(t) );
>         else
>             this->Callback::execute( boost::ref(t) );
>     }
>
>
>     void default_execute( ::Thing const & t ) {
>         Callback::execute( boost::ref(t) );
>     }
>
> };
>
> BOOST_PYTHON_MODULE(pyplusplus){
>     bp::class_< Callback_wrapper, boost::noncopyable >( "Callback",
> bp::no_init )
>         .def( bp::init< >() )
>         .def(
>             "execute"
>             , (void ( ::Callback::* )( ::Thing const & ) )(&::Callback::execute)
>             , (void ( Callback_wrapper::* )( ::Thing const & )
> )(&Callback_wrapper::default_execute)
>             , ( bp::arg("t") ) );
>
>     bp::class_< Thing, boost::noncopyable >( "Thing", bp::no_init );
> }
>
> It was generated by Py++ and I believe it exposes your use case correctly.
>
>   
But it doesn't compile (after adding the classes Thing and Callback at
the top). I get another error that Thing::~Thing() is protected:

g++ -o doh.so -fPIC -shared -I /usr/include/python2.5 -I /usr/include -L
/usr/lib -lboost_python -lpython2.5 t.cc
t.cc: In static member function 'static void
boost::python::detail::value_destroyer<false>::execute(const volatile
T*) [with T = Thing]':
/usr/include/boost/python/detail/destroy.hpp:90:   instantiated from
'void boost::python::detail::destroy_referent_impl(void*, T& (*)())
[with T = const Thing]'
/usr/include/boost/python/detail/destroy.hpp:101:   instantiated from
'void boost::python::detail::destroy_referent(void*, T (*)()) [with T =
const Thing&]'
/usr/include/boost/python/converter/rvalue_from_python_data.hpp:135:  
instantiated from
'boost::python::converter::rvalue_from_python_data<T>::~rvalue_from_python_data()
[with T = const Thing&]'
/usr/include/boost/python/converter/arg_from_python.hpp:108:  
instantiated from 'PyObject*
boost::python::detail::caller_arity<2u>::impl<F, Policies,
Sig>::operator()(PyObject*, PyObject*) [with F = void
(Callback_wrapper::*)(const Thing&), Policies =
boost::python::default_call_policies, Sig = boost::mpl::vector3<void,
Callback_wrapper&, const Thing&>]'
/usr/include/boost/python/object/py_function.hpp:38:   instantiated from
'PyObject*
boost::python::objects::caller_py_function_impl<Caller>::operator()(PyObject*,
PyObject*) [with Caller = boost::python::detail::caller<void
(Callback_wrapper::*)(const Thing&),
boost::python::default_call_policies, boost::mpl::vector3<void,
Callback_wrapper&, const Thing&> >]'
t.cc:54:   instantiated from here
t.cc:8: error: 'virtual Thing::~Thing()' is protected
/usr/include/boost/python/detail/destroy.hpp:33: error: within this context

Which isn't surprising as your code uses the same method signatures in
Callback_wrapper as mine, and does the same set of def()'s...

Paul



More information about the Cplusplus-sig mailing list