簡體   English   中英

使用 Boost Python,我可以包裝 C++ 重載運算符“+=”、“-=”、“*=”,但不能包裝“/=”?

[英]Using Boost Python, I can wrap C++ overloaded operators “+=”, “-=”, “*=”, but not “/=”?

Boost Python 有一個非常簡單的包裝重載運算符的方法。 The tutorial for exposing C++ classes, methods, etc. at boost.org ( https://www.boost.org/doc/libs/1_66_0/libs/python/doc/html/tutorial/tutorial/exposing.html ) gives this例子:

重載的 C++ 運算符,例如 class,FilePos:

class FilePos { /*...*/ };

FilePos     operator+(FilePos, int);
FilePos     operator+(int, FilePos);
int         operator-(FilePos, FilePos);
FilePos     operator-(FilePos, int);
FilePos&    operator+=(FilePos&, int);
FilePos&    operator-=(FilePos&, int);
bool        operator<(FilePos, FilePos);

如何將 map 轉換為 Python:

class_<FilePos>("FilePos")
    .def(self + int())          // __add__
    .def(int() + self)          // __radd__
    .def(self - self)           // __sub__
    .def(self - int())          // __sub__
    .def(self += int())         // __iadd__
    .def(self -= other<int>())
    .def(self < self);          // __lt__

我有一個名為“Angle”的 C++ class 代表一個角度。 它具有重載的運算符,包括“+=”、“-=”、“*=”和“/=”。 每個重載運算符都設計為將某些 double 類型的輸入與角度 class 保持的度值相加、減、乘或除。 Angle class 包裝器以與上面示例中描述的完全相同的方式映射這些重載運算符。 當我在 Python 中測試加法、減法和乘法運算符時,它們工作得非常好。 除法運算符,並非如此。 當我像這樣運行一個簡單的測試時:

A = Angle(1) # instantiate Angle object with magnitude of 1 radian
A /= 2.0 # attempt to divide the radian measurement by 2

我收到以下錯誤:

TypeError: unsupported operand type(s) for /=: 'Angle' and 'float'

基於這個問題:

嘗試重載運算符“/”時出錯

我看到 Python3(我正在使用的版本)有一種獨特的方式來理解“/”字符。 但是,此解決方案對我不起作用,因為我使用的 class 是包裝的 C++ class。

My question: is there a way to map the overloaded operator "/=" from C++ to python using boost in such a way that retains the same syntax (ie not writing a thin wrapper in C++ called "selfdiv" that performs the same operation,但必須用“Angle.selfdiv()”調用)? 也許某種方式可以覆蓋 Python 如何解釋該正斜杠字符?

Python 3 改變了除法運算符的定義方式,Boost.Python 的自動生成版本使用舊的 Python 2 樣式進行就地除法,不再有效。 這似乎是一個疏忽,因為非就地版本已更新為 Python 3 的__truediv__魔術方法。 關於這件事有一個開放的 GitHub 問題 在它得到修復之前,您可以像定義任何其他 class 成員 function 一樣定義__itruediv__和/或__ifloordiv__

class_<Foo>("Foo")
    .def(
        "__itruediv__",
        &Foo::operator/=,
        return_self<>{}
    );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM