Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 包装C++;cython中以函数指针作为模板参数的代码 我试图包装下面的Cython C++中的声明:< /P> template<typename T, double (*distance)(const DataPoint&, const DataPoint&)> class VpTree {...}_Python_C++_Cython - Fatal编程技术网

Python 包装C++;cython中以函数指针作为模板参数的代码 我试图包装下面的Cython C++中的声明:< /P> template<typename T, double (*distance)(const DataPoint&, const DataPoint&)> class VpTree {...}

Python 包装C++;cython中以函数指针作为模板参数的代码 我试图包装下面的Cython C++中的声明:< /P> template<typename T, double (*distance)(const DataPoint&, const DataPoint&)> class VpTree {...},python,c++,cython,Python,C++,Cython,我想用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

我想用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黑客实现了这一目标

这里有一个简单得多的例子:

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

Cython认为Val2是一种类型(别名为代码> int <代码>),但在生成的C++代码(<代码> Fund)>代码>中用“代码> 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代码中的其他任何地方使用“欧几里德距离”,你实际上根本不需要包装“欧几里德距离”。

哇,这是一个巧妙的技巧。我以前从未遇到过。非常感谢!
%%cython --cplus            
...
cdef extern from *:
    ctypedef int val2 "2" 

def doit():
    return fun[val2]()
%%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]()