2017-03-05 15 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

コンストラクタの末尾に '' 'except" + "'を追加して、コンストラクタのために例外が発生していないかどうかを確認しましたか? – 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 varargs)は、C++型の推論メカニズムによって最も低い優先順位が与えられますが、それ以外は何も一致しません。したがって、sum(3)sum(int)より先にsum(...)を選択します。これはまた、Cythonが型についてあまりにも難しいことを考えるのを止め、C++に任せます(必要に応じて)。欠点は、あなたが無意味な巨大な引数のリストを渡しても、あなたが暗黙のうちに(...)バージョンを呼び出すだけでは、あなたに伝わらないということです。

このハックはコンストラクタでは機能しません。また、コンストラクタで作業するのは容易ではありません。

1

最初の部分のyou referenceは、既存のC++クラスへのインターフェイスの公開の例を示しています。このような場合、オーバーロードされたメソッドが許可されます。私は、Cythonでクラスを実装するときにオーバーロードが許可されているとは思わない。ページの2番目の部分では、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__も指定していないため、デフォルトのコンストラクタでは引数が不要です。

関連する問題