【发布时间】:2012-07-02 20:14:45
【问题描述】:
我有一个类Type,它不能被复制,也不包含默认构造函数。
我有第二类A,它充当上述类的集合。第二个类通过迭代器提供访问权限,而我的迭代器具有取消引用运算符:
class A {
class iterator {
[...]
public:
Type & operator*()
{
return instance;
}
private:
Type instance;
}
[...]
};
现在公开我写了一个看起来像这样的boost::python代码:
class_<A>("A", [...])
.def("__iter__", iterator<A, return_internal_reference<> >())
.def("__len__", container_length_no_diff<A, A::iterator>)
;
将打印消息添加到 Python 代码的所有迭代器操作(构造、赋值、取消引用、销毁)后,如下所示:
for o in AInstance:
print o.key
我得到输出(修剪到重要部分):
construct 0xffffffff7fffd3e8
dereference: 0xffffffff7fffd3e8
destroy 0xffffffff7fffd3e8
get key 0xffffffff7fffd3e8
在上面的代码中,这些地址只是instance 成员的地址(或方法调用中的this)。
前三行由iterator 生成,第四行由Type 中的getter 方法打印。所以不知何故 boost::python 以这样的方式包装所有内容:
- 创建迭代器
- 取消引用迭代器并存储引用
- 销毁迭代器(及其包含的对象)
- 使用第二步获得的参考
很明显,return_internal_reference 的行为不像声明的那样(注意它实际上只是 with_custodian_and_ward_postcall<> 上的 typedef),只要引用了方法调用的结果,它就应该保留对象。
所以我的问题是如何使用boost::python 向 Python 公开这样的迭代器?
编辑:
正如有人指出的那样,可能不清楚:原始容器不包含Type 类型的对象。它包含一些BaseType 对象,我可以从中构造/修改Type 对象。所以上面例子中的iterator就像transform_iterator一样。
【问题讨论】:
标签: c++ boost reference boost-python