ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> cpp-sig
cpp-sig
[C++-sig] [python] Function objects in place of member functions
by Ravi other posts by this author
Oct 10 2009 9:14AM messages near this date
[C++-sig] Boost.python: extracting an array | Re: [C++-sig] [python] Function objects in place of member functions
Hello,
  If a free function 'func' has X* as its first argument, then, boost.python 
allows it to be bound to a member function on the python side, i.e., the 
following is legal:
  void func( X* x, arg1_t arg ) { ... }
  class_<X> ( "X" ).def( "func", &func );

In order to use a function object in place of a free function, one must 
specialize/overload
  boost::python::detail::get_signature
which, for some reason, does not account for function objects. Here's a very 
simple example that works:

----------------------------------------------
#include <boost/mpl/vector.hpp> 

struct X { int y; };

// Function object
struct Z { int operator()( X *x, int z ) { return z + x-> y; } };

namespace boost { namespace python { namespace detail {
mpl::vector<int, X*, int>  get_signature( Z&, X* )
  {return mpl::vector<int, X*, int> ();}
}}}

#include <boost/python/class.hpp> 
#include <boost/python/module.hpp> 

BOOST_PYTHON_MODULE( mft ) {
  boost::python::class_<X> ( "X" )
    .def( "z", Z() ).def_readwrite( "y", &X::y ); }
-------------------------------------------------

However, note that the overload of get_signature precedes the inclusion of the 
boost.python headers, which is extremely inconvenient. However, if the headers 
are moved to their proper location as in the following,

----------------------------------------------
#include <boost/mpl/vector.hpp> 
#include <boost/python/class.hpp> 
#include <boost/python/module.hpp> 

struct X { int y; };

// Function object
struct Z { int operator()( X *x, int z ) { return z + x-> y; } };

namespace boost { namespace python { namespace detail {
boost::mpl::vector<int, X*, int>  get_signature( Z&, X* )
  {return boost::mpl::vector<int, X*, int> ();}
}}}

BOOST_PYTHON_MODULE( mft ) {
  boost::python::class_<X> ( "X" )
    .def( "z", Z() ).def_readwrite( "y", &X::y ); }
-------------------------------------------------

the compilation fails with the following error message (gcc 4.4.1 with boost 
1.37 or 1.39):

$ g++ -Wall -shared -o mft.so memft.cc -lboost_python-mt -
I/usr/include/python2.6 -fPIC
In file included from memft.cc:1:
/usr/include/boost/python/class.hpp: In member function ‘void 
boost::python::class_<T, X1, X2, X3> ::def_impl(T*, const char*, Fn, const 
Helper&, ...) [with T = X, Fn = Z, Helper = 
boost::python::detail::def_helper<const char*, 
boost::python::detail::not_specified, boost::python::detail::not_specified, 
boost::python::detail::not_specified> , W = X, X1 = 
boost::python::detail::not_specified, X2 = 
boost::python::detail::not_specified, X3 = 
boost::python::detail::not_specified]’:
/usr/include/boost/python/class.hpp:235:   instantiated from 
‘boost::python::class_<T, X1, X2, X3> & boost::python::class_<T, X1, X2, 
X3> ::def(const char*, F) [with F = Z, W = X, X1 = 
boost::python::detail::not_specified, X2 = 
boost::python::detail::not_specified, X3 = 
boost::python::detail::not_specified]’
memft.cc:16:   instantiated from here
/usr/include/boost/python/class.hpp:536: error: no matching function for call 
to ‘get_signature(Z&, X*)’

Why is the overloaded get_signature not picked up when it is declared *after* 
the inclusion of the headers?

The reason for using function objects is to change the argument types of a 
member function of X as seen by python; for example, the functor would have an 
argument type 'double' and would then internally convert the received 'double' 
argument from the python side into some custom type prior to passing it to the 
member function of X. In other words, the functor would act as a C++ 
equivalent of a python decorator.

Regards,
Ravi

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@[...].org
http://mail.python.org/mailman/listinfo/cplusplus-sig
Thread:
Ravi
Troy D. Straszheim
Ravi
Troy D. Straszheim
Ravi
Troy D. Straszheim
Ravi
Troy D. Straszheim
Ravi
Lists Ravi
Troy D. Straszheim
Troy D. Straszheim

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved