【发布时间】:2014-09-17 19:15:04
【问题描述】:
当我尝试使用以下 Cython 代码时,我收到了我在最后发布的关于 operator() 未定义的错误。看来,当我尝试使用运算符时,Cython 不会将其解释为成员函数(注意 C++ 源代码中没有成员访问)。如果我尝试调用 prng.operator()(),那么 Cython 将无法翻译。
在 Cython 中使用运算符重载需要一些特殊的东西吗?
import numpy as np
cimport numpy as np
cdef extern from "ratchet.hpp" namespace "ratchet::detail":
cdef cppclass Ratchet:
Ratchet()
unsigned long get64()
cdef extern from "float.hpp" namespace "prng":
cdef cppclass FloatPRNG[T]:
double operator()()
cdef FloatPRNG[Ratchet] prng
def ratchet_arr(np.ndarray[np.float64_t, ndim=1] A):
cdef unsigned int i
for i in range(len(A)):
A[i] = prng()
def ratchet_arr(np.ndarray[np.float64_t, ndim=2] A):
cdef unsigned int i, j
for i in range(len(A)):
for j in range(len(A[0])):
A[i][j] = prng()
ratchet.cpp: In function ‘PyObject* __pyx_pf_7ratchet_ratchet_arr(PyObject*, PyArrayObject*)’:
ratchet.cpp:1343:162: error: ‘operator()’ not defined
*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_A.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_A.diminfo[0].strides) = operator()();
受 Ianh 启发的更多信息。看来operator()在对象被堆栈分配时不能使用
cat thing.pyx
cdef extern from 'thing.hpp':
cdef cppclass Thing:
Thing(int)
Thing()
int operator()()
# When this function doesn't exist, thing.so compiles fine
cpdef ff():
cdef Thing t
return t()
cpdef gg(x=None):
cdef Thing* t
if x:
t = new Thing(x)
else:
t = new Thing()
try:
return t[0]()
finally:
del t
cat thing.hpp
#pragma once
class Thing {
int val;
public:
Thing(int v): val(v) {}
Thing() : val(4) {}
int operator()() { return val; }
};
【问题讨论】:
-
好问题...最好包含完整的错误消息...您是在告诉 Cython 编译器这是 C++ 应用程序而不是 C 应用程序吗?
-
@SaulloCastro 谢谢你的建议。我告诉 Cython 生成 C++ 代码。这个错误实际上来自 gcc。 Cython 翻译成功。 gcc 在这里抱怨是对的,因为没有与
operator()关联的对象被调用。如果我改为调用 prng 的不同成员函数,则代码中会有成员尊重。 -
这看起来像是一个尚未实现的功能。我尝试整理一个简单的示例,但它不起作用。不过,this question 的答案有一个简单的解决方法。如果您愿意,我可以发布一个更完整的示例。不过确实不太理想。这可能会很好地出现在邮件列表中。
-
嗯。不,文档确实说现在支持运算符重载。
operator()没有任何警告。这绝对是一个错误。 -
啊,我好像说得太早了。我仍然没有看到您的代码有问题,但我会发布一个工作示例。希望这会有所帮助。