为什么boost :: python迭代器会跳过第一个元素?

kpx1894

尝试在C ++中使用Python实现可迭代对象时遇到一个奇怪的问题(使用boost :: python)。Python似乎总是取消引用前面的一个元素,因此,结果是它跳过了第一个元素,同时也取消了对“ end”元素的引用。我也不确定是否正确选择了返回值策略,但是如果我将int替换为std :: string作为元素类型,这似乎是唯一可以正常工作的策略。故意选择了迭代器标记-我打算实现可迭代对象以访问只能被遍历一次的资源。

C ++代码:

#include <Python.h>
#include <boost/python.hpp>

#include <iostream>
#include <iterator>

int nextInstance{0};

class Foo
{
public:
    class iterator : public std::iterator<std::input_iterator_tag, int>
    {
    public:
        iterator() = delete;
        iterator& operator=(const iterator&) = delete;

        iterator(const iterator& other)
        :
            instance_(nextInstance++),
            pos_(other.pos_)
        {
            std::cout << instance_ << " copy ctor " << other.instance_ << " (" << pos_ << ")\n";
        }

        explicit iterator(int pos)
        :
            instance_(nextInstance++),
            pos_(pos)
        {
            std::cout << instance_ << " ctor (" << pos_ << ")\n";
        }

        bool operator==(iterator& other)
        {
            std::cout << instance_ << " operator== " << other.instance_ << " (" << pos_ << ", " << other.pos_ << ")\n";

            return pos_ == other.pos_;
        }

        int& operator*()
        {
            std::cout << instance_ << " operator* (" << pos_ << ")\n";

            return pos_;
        }

        iterator operator++(int)
        {
            ++pos_;

            std::cout << instance_ << " operator++ (" << pos_ << ")\n";

            return *this;
        }

        ~iterator()
        {
            std::cout << instance_ << " dtor\n";
        }

    private:
        const int instance_;
        int       pos_{0};

    };

    iterator begin()
    {
        std::cout << "begin()\n";

        return iterator(0);
    }

    iterator end()
    {
        std::cout << "end()\n";

        return iterator(3);
    }
};

BOOST_PYTHON_MODULE(pythonIterator)
{
    boost::python::class_<Foo, boost::noncopyable>("Foo", boost::python::init<>())
        .def("__iter__", boost::python::iterator<Foo, boost::python::return_value_policy<boost::python::copy_non_const_reference>>{});
}

Python代码:

#!/usr/bin/python

import pythonIterator

foo = pythonIterator.Foo()

for i in foo:
    print i

输出:

end()
0 ctor (3)
begin()
1 ctor (0)
2 copy ctor 1 (0)
3 copy ctor 0 (3)
1 dtor
0 dtor
4 copy ctor 2 (0)
5 copy ctor 3 (3)
3 dtor
2 dtor
4 operator== 5 (0, 3)
4 operator++ (1)
6 copy ctor 4 (1)
6 operator* (1)
6 dtor
1
4 operator== 5 (1, 3)
4 operator++ (2)
7 copy ctor 4 (2)
7 operator* (2)
7 dtor
2
4 operator== 5 (2, 3)
4 operator++ (3)
8 copy ctor 4 (3)
8 operator* (3)
8 dtor
3
4 operator== 5 (3, 3)
5 dtor
4 dtor
巴里

后增量运算符中有一个错误。具体来说,你实行的是-Increment,不-Increment:

iterator operator++(int)
{
    ++pos_;
    return *this;  // return value *after* having incremented it
}

正确的实现是:

iterator operator++(int)
{
    iterator tmp(*this);
    ++pos_;
    return tmp; // return saved tmp *before* having incremented it
}

修复之后:

>>> list(pythonIterator.Foo())
... snip lots of output ...
[0, 1, 2]

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么for循环会更改for循环中的列表后跳过第一个元素?

为什么`zip`从第一个迭代器中又吃了一个元素?

为什么这个java迭代器循环也打印第一个元素?

为什么在Ruby中使用keep_if会跳过数组中的第一个元素?

为什么对多个流进行迭代仅对第一个元素进行迭代?

为什么 apply 跳过用于参数的数组的第一个元素?

如果findFirst()找到的第一个元素为null,为什么会抛出NullPointerException?

Selenium / Python:为什么在我的for循环迭代中找到第一个元素后,为什么Selenium find_element_不再通过查找元素了?

为什么在第二次迭代中跳过第一个字符

为什么使用扫描仪要求用户输入的 Java while 循环会跳过第一个输入

为什么Python中没有第一个(可迭代的)内置函数?

为什么不附加第一个元素

为什么在无服务器中响应的第一个元素为空?

为什么浏览器会忽略我CSS文件中的第一个选择器?

当第一个元素为null时,为什么FluentIterable.first()会引发NPE

为什么 Doctrine PostPersist Event 会错过我的装置类的第一个 Instance 元素?

为什么将0作为数组的第一个元素会阻止“ for”循环执行。[JavaScript]

为什么xargs传递给subshell时会跳过第一个参数?

为什么 yytext 跳过 YACC 中的第一个输入?

为什么我的程序在For循环的第一个循环后跳过cin>>?

为什么 for 循环跳过第一个 i++

为什么第二个for循环会覆盖Python中的第一个?

为什么<table>的<tr>元素超出第一个元素却不增加表的childElementCount?

为什么第一个AJAX调用会重置我的视图参数?

为什么追加到dict会更改第一个列表?

为什么在python中设置pop返回第一个元素而list pop返回最后一个元素

为什么VecDeque的尾部成员指向第一个元素而不是最后一个元素?

为什么第一个元素与最后一个元素之间的距离减小了?

为什么我的代码输出中的第一个和最后一个值会翻倍?