[C++-sig] Exporting an abstract class with virtual bool operator()(int)=0

Achim H. achim-bpl at mol-net.com
Wed Mar 29 15:09:42 CEST 2006


Hi!

IMHO, boost::python doesn't know that condition_Wrap is derived from 
condition, you'd have to mention that in the class_<>() statement.

Achim.

Pedro Crespo Valero wrote:

> Hello everybody,
> 
> I would like to export to python a function object that acts as a
> predicate to specify "what
> to filter" in my member function A::filter(pred). The point is that I
> would like to define the predicates
> in python so I decided to use an abstact class that I call "condition".
> I include a little example below to clarify my problem.
> Everything goes well and compiles but as you will see below I have
> problems when I use it in python.
> I would really appreciate if you could clarify me why is this happening
> and some clue to solve it,
> Thank you very much in advance for you help.
> Pedro.
> 
> 
> ////////////////////////////////////////////
> 
> #include <boost/python.hpp>
> #include <vector>
> 
> // An abstract class
> struct condition{
>     virtual bool operator()(const int ii)=0;
>     virtual ~condition(){}
> };
> 
> const int vals[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
> 
> class A{
> private:
>     std::vector<int> values_;
>     std::vector<int> fvalues_;
> public:
>     A():values_(vals[0],vals[9]+1), fvalues_(0){}
> 
>     void filter(condition& pred)
>     {
>         fvalues_.resize(0);
>         for (std::size_t i=0; i<values_.size(); i++){
>             if (pred(values_[i]))
>                 fvalues_.push_back(values_[i]);
>         }
>     }
> 
> };
> 
> //::::::::::::::::::::BOOST::PYTHON in action:::::::::::::::::::::::::
> using namespace boost::python;
> 
> struct condition_Wrap: condition, wrapper<condition>{
>     bool operator()(const int ii){ return
> call<bool>(this->get_override("operator()").ptr(),ii);}
> };
> 
> BOOST_PYTHON_MODULE(test2py)
> {
>     class_<condition_Wrap, boost::noncopyable>("condition")
>         .def("__call__", pure_virtual(&condition::operator()))
>         ;
> 
>     class_<A>("A")
>         .def("filter",&A::filter)
>         ;
> }
> 
> 
> In python::::::::::::::::::::::::::::::::::::::::::::::
> 
> from test2py import *
> 
> # inherit condition and override __call__
> class less_than(condition):
>     def __init__(self,NoMx):
>         self.max=NoMx
> 
>     def __call__(self,n):
>         return (n<self.max)
> 
> 
> x=A()
> x.filter(less_than(5))
> 
> 
> And then BOOM!!!!  the output is the following....
> 
> Traceback (most recent call last):
>   File "d:\My_Documents\pysource\test.py", line 19, in ?
>     x.filter(less_than(5))
> ArgumentError: Python argument types in
>     A.filter(A, less_than)
> did not match C++ signature:
>     filter(class A {lvalue}, struct condition {lvalue})
> 
> 
> Thanks again!!
> Long life to Boost.python !!!  :-D
> 



More information about the Cplusplus-sig mailing list