2017-03-05 29 views
5

Cython文檔shows如何用重載的方法聲明現有的C++類。cppclass Cython/C++定義中的重載是否被破壞?

但是,如果我定義我自己cppclass與重載的方法...

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 

...我得到

函數簽名不匹配先前的聲明

重載構造函數給出了相同的錯誤:

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 

我這樣做是不正確的,還是這個功能缺失?

更新:默認參數似乎是不可用太:

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() 

...通過用Cython,但得到由C++編譯器( 「錯誤的參數數目」)

+0

你有沒有嘗試在構造函數的末尾添加''',除了+'''以查看是否有任何異常因構造函數而發生? – Crt

+0

也許更改其中一個功能的名稱,因爲它們具有相同的名稱 – Crt

+0

*它們具有相同的名稱* - 超載 – MaxB

回答

3

正如我在評論中所說:這顯然是一個錯誤/不支持的功能,因此在Cython issues list on github上報告它可能比在此處發佈更有用。

然而,如果你有興趣,然後哈克短期workround了以下工作:

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) 

它使用2個招數

  1. 用Cython讓你指定一個「實際「通過將它放在引號中來表示函數的名稱。因此float sum2 "sum"(int z):最終調用函數sum,但它會欺騙Cython,使其不會註冊,而不會重複使用相同的名稱。自動C++類型扣除將正常工作。

  2. ...(即C可變參數)將匹配任何內容,但它被C++類型演繹機制賦予最低優先級。因此sum(3)選擇sum(int)提前sum(...)。這也阻止了Cython對於類型的思考,並將其留給了C++(根據需要)。缺點是它不會告訴你,如果你傳遞了一個巨大的無意義的參數列表,但只會靜靜地調用(...)版本。

這種破解不適用於構造函數,並且看起來不容易讓構造函數工作。

1

的絆倒頁面you reference的第一部分顯示了向現有C++類公開接口的示例。在這種情況下,允許重載的方法。我不認爲在Cython中實現類時允許重載。本頁的第二部分展示瞭如何實現包裝器 - 用於包裝C++類的Cython類。看看例子:

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) 

構造函數被命名爲__cinit__。它與Python中的相似。 Cython語法就像在Python中一樣。我不認爲你可以將你的構造函數命名爲類名。您沒有提供__init____cinit__,因此默認構造函數不需要參數。

相關問題