我正在尝试使用以下代码将元组上的迭代器从 C++ 导出到 Python:
class PyContainer
{
public:
PyContainer(int maxSize) : maxSize(maxSize) { cout << "Constructor called with maxSize = " << maxSize << endl; }
boost::python::tuple AllocateTuple(int idx)
{
cout << "Allocating pyRecord " << idx << endl;
return boost::python::make_tuple(idx);
}
class iterator : public std::iterator<std::input_iterator_tag, boost::python::tuple>
{
public:
iterator(const iterator& rhs) : idx(rhs.idx), currTuple(rhs.currTuple), self(rhs.self) { cout << "copy iterator(rhs.idx=" << rhs.idx << ", currTuple=" << currTuple.ptr()<< ")" << endl; }
iterator(PyContainer *self, int idx) : idx(idx), currTuple(), self(self) { cout << "iterator(idx=" << idx << ")" << endl; }
~iterator() { cout << "~iterator " << currTuple.ptr()<< endl; }
boost::python::tuple& operator*()
{
cout << "operator* " << currTuple.ptr()<< endl;
return currTuple;
}
// Pre-increment
iterator& operator++()
{
cout << "preinc " << currTuple.ptr()<< endl;
++idx;
return *this;
}
// Post-increment.
iterator operator++(int)
{
currTuple = self->AllocateTuple(idx);
cout << "postinc " << currTuple.ptr()<< endl;
iterator tmp(*this);
operator++();
return tmp;
}
// Comparison.
bool operator==(const iterator& rhs) { return this->idx == rhs.idx; }
bool operator!=(const iterator& rhs) { return !this->operator==(rhs); }
private:
int idx;
boost::python::tuple currTuple;
PyContainer* self;
};
iterator begin() { return iterator(this, 0); }
iterator end() { return iterator(this, maxSize); }
private:
int maxSize;
};
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
class_<PyContainer, boost::noncopyable>("PyContainer", init<int>())
.def("__iter__", boost::python::iterator<PyContainer, return_internal_reference<>>())
;
}
在python中,我使用这样的迭代器:
import hello_ext as a
r = a.PyContainer(2)
for i in r:
print i
C++ 的输出如下所示:
构造函数调用 迭代器(idx=2) 复制迭代器(rhs.idx=2,currentRecord=005D1030) ~迭代器 005D1030 迭代器(idx=0) 复制迭代器(rhs.idx=0,currentRecord=005D1030) ~迭代器 005D1030 复制迭代器(rhs.idx=0,currentRecord=005D1030) 复制迭代器(rhs.idx=2,currentRecord=005D1030) ~迭代器 005D1030 ~迭代器 005D1030 复制迭代器(rhs.idx=0,currentRecord=005D1030) 复制迭代器(rhs.idx=2,currentRecord=005D1030) ~迭代器 005D1030 ~迭代器 005D1030 0==2 分配 pyRecord 0 邮政编码 008F7970 复制迭代器(rhs.idx=0,currentRecord=008F7970) preinc 008F7970 复制迭代器(rhs.idx=0,currentRecord=008F7970) ~迭代器 008F7970 操作员* 008F7970 ~迭代器 008F7970
我是否必须从 Python 管理对象的生命周期?