Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is overloading broken in cppclass Cython/C++ definitions?

Tags:

python

cython

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 this incorrectly, or is this feature missing?

Update: Default arguments seem to be unusable too:

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 gets tripped up by the C++ compiler ("wrong number of arguments")

like image 931
MWB Avatar asked Mar 05 '17 15:03

MWB


1 Answers

As I said in a comment: this clearly is a bug/unsupported feature, and so it's probably much more useful to report it on the Cython issues list on github than post it here.

However, if you're interested in a hacky short-term workround then the following works:

    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)

This uses 2 tricks

  1. Cython lets you specify an "actual" name for the function by putting it in quotes. Thus float sum2 "sum"(int z): ends up calling the function sum, but it tricks Cython so that it doesn't register than you've reused the same name. The automatic C++ type deduction will work correctly though.

  2. ... (i.e. C varargs) will match anything but it given the lowest priority by the C++ type deduction mechanism. Therefore sum(3) picks sum(int) ahead of sum(...). This also stops Cython thinking too hard about the types and leaves it up to C++ (as desired). The downside is that it won't tell you if you pass a huge nonsensical list of arguments but will just silently call the (...) version.

This hack doesn't work for constructors, and doesn't look easy to make work for constructors.

like image 57
DavidW Avatar answered Nov 15 '22 14:11

DavidW