如何使用boost :: python :: iterator和return_internal_reference? [英] How to use boost::python::iterator with return_internal_reference?

查看:613
本文介绍了如何使用boost :: python :: iterator和return_internal_reference?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类类型不能被复制也不包含默认构造函数。
我有第二个类 A 作为一组上述类。第二个类通过迭代器访问,我的迭代器有解引用操作符:

I have a class Type which cannot be copied nor it contains default constructor. I have second class A that acts as a set of the above classes. This second class gives access via iterators and my iterator has dereference operator:

class A {
    class iterator {
        [...]
      public:
        Type & operator*()
        { 
            return instance;
        }
      private:
        Type instance;
    }
    [...]
};

现在公开我写了一个 boost :: python 代码如下:

Now to expose that I wrote a boost::python code that looks like that:

class_<A>("A", [...])
    .def("__iter__", iterator<A, return_internal_reference<> >())
    .def("__len__", container_length_no_diff<A, A::iterator>)
;

向所有迭代器操作(构造,赋值,解引用,销毁)添加打印消息后,这:

After adding print messages to all iterator operations (construction, assignment, dereferences, destruction) for code Python like this:

for o in AInstance:
    print o.key

我获得输出(修整为重要部分):

I get output (trimmed to important part):

construct 0xffffffff7fffd3e8
dereference: 0xffffffff7fffd3e8
destroy 0xffffffff7fffd3e8
get key 0xffffffff7fffd3e8

在上面的代码中,这些地址只是方法调用中 instance 成员(或 this )的地址。
前三行由迭代器生成,第四行由类型中的getter方法打印。所以不知何故 boost :: python 以这样的方式包装一切:

In above code those addresses are just addresses of instance member (or this in method call). First three lines are produced by iterator, the fourth line is printed by getter method in Type. So somehow boost::python wraps everything in such manner that it:




  1. 取消引用迭代器并存储引用

  2. 销毁迭代器b
  3. 使用第二步中获得的引用

很清楚 return_internal_reference (注意它实际上只是typedef在 with_custodian_and_ward_postcall<> ),它应该保持对象只要方法调用的结果引用。

So clearly return_internal_reference does not behave like stated (note that it actually is just typedef over with_custodian_and_ward_postcall<>) where it should keep object as long as result of method call is referenced.

所以我的问题是如何使用 boost :: python 将这样的迭代器暴露给Python?

So my question is how do I expose such an iterator to Python with boost::python?

编辑

由于指出可能不清楚:原始容器不包含对象类型。它包含一些 BaseType 对象,从中我可以构造/修改类型对象。所以 iterator 在上面的例子中就像 transform_iterator

As it was pointed out it might not be clear: the original container does not contain objects of type Type. It contains some BaseType objects from which I am able to construct/modify Type object. So iterator in above example acts like transform_iterator.

推荐答案

我认为整个问题是,我不完全明白什么语义应该迭代器类提供。
看来,只要容器存在,而不是迭代器,迭代器返回的值必须有效。

I think the whole problem was that I did not fully understand what semantics should iterator class provide. It seems that value returned by iterator has to be valid as long as container exists, not iterator.

这意味着 boost: :python 行为正确,有两个解决方案:

This means that boost::python behaves correctly and there are two solutions to that:


  • 使用 :shared_ptr

  • 返回值

编辑:
我已经制定了一个方法,而不是我试图做的,解决方案(不仅可能,但它似乎工作很好): Boost python容器,迭代器和项目生命周期

这篇关于如何使用boost :: python :: iterator和return_internal_reference?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆