[C++-sig] Can't use make_function to wrap base class method?

David Abrahams dave at boost-consulting.com
Tue Dec 13 23:17:09 CET 2005


Alex Mohr <amohr at pixar.com> writes:

> Seems I can't wrap a base class method of a derived class if I use 
> make_function.  Is this expected?  Here's an example.
>
> #include <boost/python.hpp>
> using namespace boost::python;
>
> class Base {
> public:
> 	int method() { return 1; }
> };
>
> class Derived : public Base {};
>
> BOOST_PYTHON_MODULE(Foo) {
> 	class_<Derived>("Derived", "", init<>())
> 		.def("method", make_function(&Derived::method))
> 		.def("method2", &Derived::method)
> 	;
> }
>
>  >>> from Foo import *
>  >>> Derived().method()
> Traceback (most recent call last):
>    File "<stdin>", line 1, in ?
> Boost.Python.ArgumentError: Python argument types in
> 	Derived.method(Derived)
> did not match C++ signature:
> 	method(Base {lvalue})
>
>  >>> Derived().method2()
> 1
>
> Seems like this should work.  Wrapping a method in make_function
> seems to make it not.  This becomes cumbersome since the only way I
> know of to supply return_value_policies in .add_property is to use
> make_function.

You either need to wrap Base or you need to 

		.def(
             "method", 
              make_function(
                (int (Derived::*)()) &Derived::method
              )
         )

class_ has the information about the derived class (it's a template
argument), so it can do the cast automagically.  However,
make_function is just a function, so it can't do anything fancy with
Derived.  The function pointer's type is 

  int (Base::*)()

even when you get it via &Derived::method.

HTH,

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com




More information about the Cplusplus-sig mailing list