Does the break in Cython / C ++ definitions overload cppclass?

The Cython documentation shows how to declare existing C ++ classes with overloaded methods.

However, if I define my own cppclass with an overloaded method ...

 cdef cppclass point: float x, y point(): this.x = 0 this.y = 0 float sum(): return this.x + this.y float sum(int z): # COMPILE ERROR return this.x + this.y + z 

... I get

Function signature does not match previous declaration

Overloading the constructor gives the same error there:

 cdef cppclass point: float x, y point(): this.x = 0 this.y = 0 point(float X, float Y): # COMPILE ERROR this.x = X this.y = Y float sum(): return this.x + this.y 

Am I doing it wrong or is this feature missing?

Update: By default, the default arguments are also unsuitable:

 cdef cppclass point: float x, y point(float X=0, float Y=0): this.x = X this.y = Y float sum(): return this.x + this.y cdef float use_point(): cdef point p p = point(1, 2) return p.sum() 

... passes Cython, but crashes with the C ++ compiler ("wrong number of arguments")

+5
source share
2 answers

As I said in the comment: this is clearly a bug / unsupported function, and therefore it is probably much more useful to report this to the Cython Problem List on github than post it here.

However , if you are interested in a hacker short-term workflow, then the following work:

  float sum(...): return this.x + this.y float sum2 "sum"(int z): return this.x + this.y + z # A test function to prove it def test(): cdef point pt a = pt.sum() b = pt.sum(3) return a,b # returns (0.0, 3.0) 

It uses 2 tricks

  • Cython allows you to specify the "actual" name for a function by putting it in quotation marks. Thus, float sum2 "sum"(int z): ends the call to the sum function, but it tricks Cython so that it does not register, than you reused the same name. Automatic output like C ++ will work correctly.

  • ... (i.e. C varargs) will match anything, but it gives the lowest priority to a C ++ type subtraction mechanism. Therefore, sum(3) selects sum(int) before sum(...) . This also stops Cython from thinking too much about types and leaves it to C ++ (optional). The downside is that it will not tell you if you are passing a huge, meaningless list of arguments, but just silently call the version (...) .

This hack does not work for designers and does not look easy to work for designers.

+3
source

The page link to it in the first part shows examples of demonstrating interfaces for existing C ++ classes. In this case, overloaded methods are allowed. I do not think that overload is allowed when implementing classes in Cython. The second part of the page shows how to implement shells - Cython classes that carry C ++ classes. Take a look at an example:

 cdef class PyRectangle: cdef Rectangle c_rect # hold a C++ instance which we're wrapping def __cinit__(self, int x0, int y0, int x1, int y1): self.c_rect = Rectangle(x0, y0, x1, y1) def get_area(self): return self.c_rect.getArea() def get_size(self): cdef int width, height self.c_rect.getSize(&width, &height) return width, height def move(self, dx, dy): self.c_rect.move(dx, dy) 

The constructor is named __cinit__ . It works the same way as in Python. Cython syntax is similar to Python. I don’t think you can name your constructor the same as the class name. You did not specify __init__ and __cinit__ , so the default constructor does not expect any arguments.

+1
source

Source: https://habr.com/ru/post/1265060/


All Articles