与之前的post不同,我在这里使用所有cdef函数。如果我使用 fused_type 输入的函数指针,它将引发“融合类型的无效使用,类型无法专门化”。相反,内置类型的函数指针效果很好。为什么?
cimport cython
# raise error
ctypedef fused fused_type:
float
int
ctypedef fused_type (* _func_pointer) (fused_type[:])
cdef fused_type base_func(fused_type[:] arg1):
return arg1[0]
cdef fused_type c_entry(fused_type[:] arg1, _func_pointer func):
return func(arg1)
cdef fused_type base_wrapper(fused_type[:] arg1):
return c_entry(arg1, base_func)
""" ------- """
# works
cdef int base_func(int[:] arg1):
return arg1[0]
cdef int c_entry(int[:] arg1, _func_pointer func):
return func(arg1)
cdef int base_wrapper(int[:] arg1):
return c_entry(arg1, base_func)
您需要将其更改为
cdef fused_type base_wrapper(fused_type[:] arg1):
return c_entry(arg1, base_func[fused_type])
当
base_wrapper
被专门化时,无论 base_func
当前位于 fused_type
中,都会选择 base_wrapper
的专门化。
原因的粗略解释:
ctypedef fused_type (* _func_pointer) (fused_type[:])
这没有定义接受并返回
fused_type
的函数指针类型。相反,它定义了一个包含两种类型的融合类型:
float (*)(float[:])
int (*)(int[:])
当您单独执行
base_func
时,它不是一个“真正的”函数 - 您可以通过调用它或我手动选择它来获得其中一个专业化(例如 base_func[int]
)。
因此,在
base_wrapper
中,return c_entry(arg1, base_func)
行不知道它应该使用 base_func
的哪种专业化,因此无法选择它应该匹配的 _func_pointer
的两种类型中的哪一种。
Cython 融合类型系统相当垃圾,并没有花太多精力来解决混淆 - 它要么是明确的完全匹配,要么根本不匹配。