我尝试实现一个应该可迭代的C ++类。到目前为止,我写过:
class XYByFrameIterator {
public:
XYByFrameIterator(vector<xy>& precalc) :_precalc(precalc), _current(precalc.begin()), _end(precalc.end()) {}
XYByFrameIterator* __iter__() { cout << "__iter__" << endl; return this;}
xy& next() throw (Stop_Iteration) {
if (_current == _end)
throw Stop_Iteration();
xy& ret = *_current;
_current++;
return ret;
}
private:
vector<xy>& _precalc;
vector<xy>::iterator _current;
vector<xy>::iterator _end;
};
要将我的自定义C ++ Stop_Iteration
异常转换为Python StopIteration
异常,我将其添加到swig接口文件中:
%typemap(throws) Stop_Iteration %{
PyErr_SetNone(PyExc_StopIteration);
SWIG_fail;
%}
但不幸的是,这只适用于某些情况。例如,以下python代码按预期打印x / y值。
it = fa.xyByFrameIterator(43)
for xy in it:
print(xy.x)
print(xy.y)
但如果我直接在循环中实例化迭代器,它会崩溃:
for xy in fa.xyByFrameIterator(43):
print(xy.x)
print(xy.y)
输出:
__iter__
44.2233009338
5.83165979385
segmentation fault
更新
我在阅读answer后找到了解决方案。我认为将__iter__
方法传递给Python之后出现了问题。现在我通过swig接口文件直接在Python代码中插入__iter__
。它现在看起来像这样:
%typemap(throws) Stop_Iteration %{
PyErr_SetNone(PyExc_StopIteration);
SWIG_fail;
%}
%extend XYByFrameIterator
{
%insert("python") %{
def __iter__(self):
return self
%}
}
我的c ++代码:
class XYByFrameIterator {
public:
XYByFrameIterator(vector<xy>& precalc) :_precalc(precalc), _current(precalc.begin()), _end(precalc.end()) {}
xy& next() throw (Stop_Iteration) {
if (_current == _end)
throw Stop_Iteration();
xy& ret = *_current;
_current++;
return ret;
}
private:
vector<xy>& _precalc;
vector<xy>::iterator _current;
vector<xy>::iterator _end;
};
这项工作很安静,但我更喜欢swig接口文件中每个迭代器类没有(或更少)代码的解决方案。