如果您拥有现代的C ++编译器并且可以使用右值引用,请移动构造函数和std ::
move,这非常简单。我认为最简单的方法是为向量创建Cython包装器,然后使用move构造函数来掌握向量的内容。
显示的所有代码都在peak_detection_.pyx中。
先包好
std::move。为了简单起见,我只包装了我们想要的一种情况(
vector<Peak>),而不是弄乱模板。
cdef extern from "<utility>": vector[Peak]&& move(vector[Peak]&&) # just define for peak rather than anything else
其次,创建向量包装器类。这定义了像列表一样访问它所必需的Python函数。它还定义了一个函数来调用移动分配运算符
cdef class PyPeakVector: cdef vector[Peak] vec cdef move_from(self, vector[Peak]&& move_this): self.vec = move(move_this) def __getitem__(self,idx): return PyPeak2(self,idx) def __len__(self): return self.vec.size()
然后定义包装的类
Peak。这与您的其他类稍有不同,因为它不拥有
Peak包装的内容(向量包含)。否则,大多数功能保持不变
cdef class PyPeak2: cdef int idx cdef PyPeakVector vector # keep this alive, since it owns the peak rather that PyPeak2 def __cinit__(self,PyPeakVector vec,idx): self.vector = vec self.idx = idx cdef Peak* getthisptr(self): # lookup the pointer each time - it isn't generally safe # to store pointers incase the vector is resized return &self.vector.vec[self.idx] # rest of functions as is # don't define a destructor since we don't own the Peak
最后实施
getPeaks()
cdef class PyPeakDetection: # ... def getPeaks(self, data): cdef Peak peak cdef PyPeak new_peak cdef vector[Peak] peaks = self.thisptr.getPeaks(data) retval = PyPeakVector() retval.move_from(move(peaks)) return retval
替代方法:
如果
Peak是平凡的,你可以去那里你调用一个方法
move上
Peak而上的向量,为您建造
PyPeak秒。对于这种情况,您在此处移动和复制将等同于`Peak。
如果您不能使用C 11功能,则需要稍微更改一下接口。不用让C
getPeaks函数返回向量,而是将一个空的向量引用(由拥有
PyPeakVector)作为输入参数并写入其中。其余的大部分包装都保持不变。



