Reputation: 53
I am having trouble accessing overloaded constructors in a C++ class through Cython. I am trying to wrap a C++ class as described here. The class has multiple constructors with the same number of arguments, differing only by type, such as the class mentioned here. However, Cython has trouble deciding which constructor to call, giving the error "no suitable method found".
For instance, given foo.h as follows
class Foo
{
public:
int which_constructor;
Foo(int){ which_constructor = 1; }
Foo(bool){ which_constructor = 2; };
~Foo();
};
and pyfoo.pyx as follows
from libcpp cimport bool as bool_t
cdef extern from "foo.h":
cdef cppclass Foo:
Foo(int)
Foo(bool_t)
int which_constructor
cdef class PyFoo:
cdef Foo *thisptr # hold a C++ instance which we're wrapping
def __cinit__( self, *args, **kwargs):
# get list of arg types to distinquish overloading
args_types = []
for arg in args:
args_types.append(type(arg))
if (args_types == [int]):
self.thisptr = new Foo(args[0])
elif (args_types == [bool]):
self.thisptr = new Foo(args[0])
else:
pass
def which_constructor(self):
return self.thisptr.which_constructor
and a setup file setup_pyfoo.py as follows
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
setup(
ext_modules = cythonize(
Extension("pyfoo", ["pyfoo.pyx"],
language="c++",
)
)
)
when I attempt to compile, I get the following error
C:\Users\bennett.OCM\Documents\Python\Cython>python setup_pyfoo.py build_ext --i
nplace
Compiling pyfoo.pyx because it changed.
Cythonizing pyfoo.pyx
Error compiling Cython file:
------------------------------------------------------------
...
for arg in args:
args_types.append(type(arg))
# four differnent constructors.
if (args_types == [int]):
self.thisptr = new Foo(args[0])
^
------------------------------------------------------------
pyfoo.pyx:20:34: no suitable method found
Error compiling Cython file:
------------------------------------------------------------
...
# four differnent constructors.
if (args_types == [int]):
self.thisptr = new Foo(args[0])
elif (args_types == [bool]):
self.thisptr = new Foo(args[0])
^
------------------------------------------------------------
pyfoo.pyx:22:34: no suitable method found
If I remove one or other of the constructor definitions in pyfoo.pyx, things work correctly, even though the multiple constructors still exist in foo.h. I suspect that Cython needs to be coerced into calling a particular constructor. I just don't know how to help it. Can anyone help me?
Upvotes: 5
Views: 1850
Reputation: 871
You can cast your arguments explicitly:
if (args_types == [int]):
self.thisptr = new Foo(<int> args[0])
elif (args_types == [bool]):
self.thisptr = new Foo(<bool_t> args[0])
else:
pass
Be sure to cast to <bool_t>
and not <bool>
, otherwise it will give you an ambiguous overloading error.
Upvotes: 3