gpt4 book ai didi

python - 在cython中用函数指针作为模板参数包装C++代码

转载 作者:行者123 更新时间:2023-11-30 03:19:38 27 4
gpt4 key购买 nike

我试图在 cython 中包装以下用 C++ 编写的声明:

template<typename T, double (*distance)(const DataPoint&, const DataPoint&)>
class VpTree
{...}

我在 C++ 中也有以下定义:

inline double euclidean_distance(const DataPoint &t1, const DataPoint &t2) {...}

我正在尝试用 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
...

并围绕它构建一个包装器:

cdef class VPTree:
cdef VpTree[DataPoint, euclidean_distance] tree

def __cinit__(self):
self.tree = VpTree[DataPoint, euclidean_distance]()

不幸的是,这会导致以下错误:

------------------------------------------------------------

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

我怀疑问题出在定义的 F 部分,我已经尝试了各种方法来代替它,例如double(*)(DataPoint&, DataPoint&) 但这显然会导致语法错误。

最佳答案

据我所知,Cython 不直接支持非类型模板参数(这就是函数指针)(虽然我可能错过了备忘录),但是有一个众所周知的 cname-hack 实现目标。

这里,举一个更简单的例子:

%%cython --cplus            
cdef extern from *:
"""
template<int val>
int fun(){return val;}
"""
int fun[T]()

即一个int -value 作为模板参数。

现在我们陷入困境:Cython 期望 T 是类型,而 g++(或其他编译器)期望一个整数值 - cname-hack 来拯救我们:

%%cython --cplus            
...
cdef extern from *:
ctypedef int val2 "2"

def doit():
return fun[val2]()

Cython 相信val2成为一种类型(int 的别名),但将其替换为 2在生成的 C++ 代码 ( fun<2>() ) 中,因此 C++ 编译器看到一个整数值(在本例中为 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]()

如果您不在 Cython 代码中的其他任何地方使用它,实际上您根本不需要包装“euclidean_distance”。

关于python - 在cython中用函数指针作为模板参数包装C++代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53582945/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com