我试图将以下用 C++ 编写的声明包装在 cython 中:
template<typename T, double (*distance)(const DataPoint&, const DataPoint&)>
class VpTree
{...}
Run Code Online (Sandbox Code Playgroud)
我还在 C++ 中得到了以下定义:
inline double euclidean_distance(const DataPoint &t1, const DataPoint &t2) {...}
Run Code Online (Sandbox Code Playgroud)
我正在尝试将其包装在 cython 中。这是我根据文档得出的结论:
cdef extern from "vptree.h":
# declaration of DataPoint omitted here
cdef inline double euclidean_distance(DataPoint&, DataPoint&)
cdef cppclass VpTree[T, F]: # F is almost certainly wrong
...
Run Code Online (Sandbox Code Playgroud)
并围绕它构建一个包装器:
cdef class VPTree:
cdef VpTree[DataPoint, euclidean_distance] tree
def __cinit__(self):
self.tree = VpTree[DataPoint, euclidean_distance]()
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会导致以下错误:
------------------------------------------------------------
cdef class VPTree:
cdef VpTree[DataPoint, euclidean_distance] tree
^
------------------------------------------------------------
unknown type in template argument
------------------------------------------------------------
cdef class VPTree:
cdef VpTree[DataPoint, euclidean_distance] tree
def __cinit__(self):
self.tree = VpTree[DataPoint, euclidean_distance]()
^
------------------------------------------------------------
unknown type in template argument
Run Code Online (Sandbox Code Playgroud)
我怀疑问题出在F定义的部分,并且我尝试了各种方法来代替它,例如,double(*)(DataPoint&, DataPoint&)但这显然会导致语法错误。
据我所知,Cython 不直接支持非类型模板参数(这就是函数指针)(虽然我可能错过了备忘录),但有一个众所周知的cname-hack可以实现这一目标。
在这里,举一个更简单的例子:
%%cython --cplus
cdef extern from *:
"""
template<int val>
int fun(){return val;}
"""
int fun[T]()
Run Code Online (Sandbox Code Playgroud)
即int-value 作为模板参数。
现在我们遇到了一个困境:Cython 期望 T 为类型,而 g++(或其他编译器)期望一个整数值 - 这里 cname -hack来拯救我们:
%%cython --cplus
...
cdef extern from *:
ctypedef int val2 "2"
def doit():
return fun[val2]()
Run Code Online (Sandbox Code Playgroud)
Cython 认为val2它是一种类型( 的别名),但在生成的 C++ 代码int中将其替换为( ),因此 c++ 编译器会看到一个整数值(在本例中),正如它所期望的那样。2fun<2>()2
对于您的情况,这意味着添加:
%%cython --cplus
...
cdef extern from *:
ctypedef int euclidean_distance_t "euclidean_distance"
cdef class VPTree:
cdef VpTree[DataPoint, euclidean_distance_t] tree
def __cinit__(self):
self.tree = VpTree[DataPoint, euclidean_distance_t]()
Run Code Online (Sandbox Code Playgroud)
如果您不在 Cython 代码中的其他任何地方使用它,实际上根本不必包装“euclidean_distance”。
| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |