Cython - 如何正确调用带有引用的运算符
Cython - how to properly call operator with references
我的 Cython 包装器中有以下代码到C++代码:
# distutils: language = c++
# distutils: sources = symbolic.cpp
from libcpp.vector cimport vector
from libcpp.pair cimport pair
from libcpp.string cimport string
from libcpp cimport bool
cdef extern from "symbolic.h" namespace "metadiff::symbolic":
cdef cppclass SymbolicMonomial:
vector[pair[int, int]] powers
long long coefficient;
SymbolicMonomial()
SymbolicMonomial(long)
SymbolicMonomial(const SymbolicMonomial&)
bool is_constant()
long long int eval(vector[int]&)
long long int eval()
string to_string()
string to_string_with_star() const
cdef SymbolicMonomial mul_mm"operator*"(const SymbolicMonomial&, const SymbolicMonomial&)
# SymbolicMonomial operator*(long long, const SymbolicMonomial&)
# SymbolicMonomial operator*(const SymbolicMonomial&, long long)
cdef class SymMonomial:
cdef SymbolicMonomial* thisptr # hold a C++ instance which we're wrapping
def __cinit__(self):
self.thisptr = new SymbolicMonomial()
def __cinit__(self, int value):
self.thisptr = new SymbolicMonomial(value)
def __dealloc__(self):
del self.thisptr
def is_constant(self):
return self.thisptr.is_constant()
def eval(self):
return self.thisptr.eval()
def __str__(self):
return self.to_string_with_star()
def to_string(self):
return self.thisptr.to_string().decode('UTF-8')
def to_string_with_star(self):
return self.thisptr.to_string_with_star().decode('UTF-8')
def __mul__(self, other):
return mul_mm(self.thisptr, other)
def variable(variable_id):
monomial = SymMonomial()
monomial.thisptr.powers.push_back((variable_id, 1))
return monomial
但是,我从来没有弄清楚如何正确调用mul_mm
方法。它一直说Cannot convert 'SymbolicMonomial' to Python object
反之亦然。问题是我需要能够以这种方式将两个对称项相乘。但是,由于某种原因,我无法掌握如何正确执行此操作的窍门。有什么建议吗?
您有许多问题:
-
你不能C++对象直接返回给 Python - 你需要返回你的包装器类型(分配给包装器的
thisptr
) -
在调用函数时,无法保证
self
或other
的类型正确(请参阅 http://docs.cython.org/src/userguide/special_methods.html#arithmetic-methods 中的注释,了解如何按任一顺序使用操作数调用方法)。要使用 Cython 类的 C/C++ 成员,您需要确保 Cython 知道该对象确实属于该类。我建议使用<Classname?>
样式转换(请注意问号),如果不匹配,则会引发异常。 -
您还需要从
other
获取thisptr
,而不仅仅是将 Python 包装类传递给您的C++函数。
以下应该有效。
def __mul__(self,other):
cdef SymMonomial tmp = SymMonomial()
cdef SymMonomial self2, other2
try:
self2 = <SymMonomial?>self
other2 = <SymMonomial?>other
except TypeError:
return NotImplemented # this is what Python expects for operators
# that don't know what to do
tmp.thisptr[0] = mul_mm(self2.thisptr[0],other2.thisptr[0])
return tmp
相关文章:
- 取消引用运算符不能重载
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 为什么在函数名称中使用取消引用" * "运算符?
- C++:类类型引用运算符=用法
- 为什么通过通用引用运算符 (&&) 将变量的引用传递给 Varadic 模板函数失败?
- 当取消引用运算符 (*) 重载时,*this 的使用是否受到影响?
- 为什么 C++ 中指向方法取消引用运算符的指针具有如此低的优先级
- 赋值不起作用,但带有取消引用运算符的地址起作用?
- 关于解引用运算符是否在表达式中产生对象对值的定义不明确
- 如何重载箭头取消引用运算符->() 不是针对实体对象,而是针对指针
- (取消)引用运算符的评估
- 重载取消引用运算符(运算符*())
- 如何重载取消引用运算符
- 结构引用和取消引用运算符
- 输入迭代器必须具有常量解引用运算符吗
- 对 std::atomic::load 的结果使用结构取消引用 (->) 运算符是否安全
- C++使用引用运算符传递数组
- 使用引用和取消引用运算符读取代码行时遇到问题
- 在C++向量中使用解引用运算符
- 是否可以根据基于的范围类型调用不同的取消引用运算符重载