创建迭代器以C++返回 std::p air 的容器

Create Iterator to C++ container that returns a std::pair

本文关键字:air std 迭代器 C++ 返回 创建      更新时间:2023-10-16

我正在尝试在C++中实现一个容器,该容器使用平面数组来存储数据,但成对迭代该数据。 现在我可以轻松地更改实现,以便容器包含std::pair向量,但是我想遍历从元素 0 或元素 1 开始的对。

为了说明我想要实现的目标,如果我的基础数组如下所示:1,2,3,4,5,6,7,8

我想定义两个迭代器,一个返回对:(1,2), (3,4), (5,6), (7,8)以及返回货币对的第二个迭代器:(2,3), (4,5), (6,7)

是否可能同时仍然允许迭代器的元素作为底层数组的引用?

可以编写自己的迭代器,该迭代器遍历元素。以下问题显示了有关如何完成此操作的一些解释:C++中的自定义迭代器。

然后,您可以将所需的值作为 std::p air 返回,并迭代到下一个元素对(通过将计数器递增 2)。

Boost 库具有迭代器适配器,允许您包装其他迭代器类型并更改或调整其功能。以下是您可以将其用于您的目的的方法:

#include <boost/iterator/iterator_adaptor.hpp>
#include <vector>
struct iterator :
    public boost::iterator_adaptor<
        iterator,                    // the name of our class, see docs for details
        std::vector<int>::iterator,  // underlying base iterator
        std::pair<int&, int&>,       // our value type
        boost::forward_traversal_tag // the category you wish to give it
    >
{
     // need this to convert from vector::iterator to ours
    explicit iterator(std::vector<int>::iterator i)
        : iterator::iterator_adaptor_(i) {}
    value_type operator*()
    {
        return value_type(
            *base_reference(),
            *(base_reference()+1)
        );
    }
};

用法示例:

std::vector<int> v {1,2,3,4};
iterator it(v.begin());
++it;
(*it).first = 0;  // TODO: operator->
(*it).second = 0;
for (int i : v) std::cout << i << ' '; // prints 1 0 0 4

您还需要覆盖比较以正确处理最终条件等。 希望有帮助。

只是想我已经在我的代码中投入了我实际使用的东西。 我不想按照@jrok的建议使用 boost,但他们答案中std::pair<int&, int&>的类型给了我一个需要什么的提示。

下面是我构造的类,它使用两个迭代器。 返回从基础数据中的偶数索引开始的对的RepeatIterator,以及返回从奇数索引开始的对的SpacerIterator

class RepeatArray {
    typedef std::vector<int> storage_t;
public:
    class RepeatIterator {
    public:
        typedef RepeatIterator self_t;
        typedef int value_t;
        typedef int& reference_t;
        typedef int* pointer_t;
        typedef std::pair<reference_t, reference_t> return_t;
        RepeatIterator(storage_t::iterator input) : current_pos(input){}
        return_t operator *() {
            return return_t(*(current_pos), *(current_pos + 1 ));
        }
        self_t operator++() { self_t i = *this; current_pos += 2; return i; }
        self_t operator++(int junk) { current_pos+=2; return *this; }

        bool operator==(const self_t& rhs) { return current_pos == rhs.current_pos; }
        bool operator!=(const self_t& rhs) { return current_pos != rhs.current_pos; }
        bool operator<(const self_t& rhs) { return current_pos < rhs.current_pos; }
        bool operator<=(const self_t& rhs) { return current_pos <= rhs.current_pos; }
        bool operator>(const self_t& rhs) { return current_pos > rhs.current_pos; }
        bool operator>=(const self_t& rhs) { return current_pos >= rhs.current_pos; }
    private:
        storage_t::iterator current_pos;
    };
    class SpacerIterator {
    public:
        typedef SpacerIterator self_t;
        typedef int value_t;
        typedef int& reference_t;
        typedef int* pointer_t;
        typedef std::pair<reference_t, reference_t> return_t;
        SpacerIterator(storage_t::iterator input) : current_pos(input){}
        return_t operator *() {
            return return_t(*(current_pos), *(current_pos + 1 ));
        }
        self_t operator++() { self_t i = *this; current_pos += 2; return i; }
        self_t operator++(int junk) { current_pos+=2; return *this; }
        bool operator==(const self_t& rhs) { return current_pos == rhs.current_pos; }
        bool operator!=(const self_t& rhs) { return current_pos != rhs.current_pos; }
        bool operator<(const self_t& rhs) { return current_pos < rhs.current_pos; }
        bool operator<=(const self_t& rhs) { return current_pos <= rhs.current_pos; }
        bool operator>(const self_t& rhs) { return current_pos > rhs.current_pos; }
        bool operator>=(const self_t& rhs) { return current_pos >= rhs.current_pos; }

    private:
        storage_t::iterator current_pos;
    };
    void add(int start, int end) {
        positions.push_back(start);
        positions.push_back(end);
    }
    void dump() {
        for (auto i : positions) {
            std::cout <<i<<",";
        }
        std::cout <<std::endl;
    }
    RepeatIterator repeatBegin(){return RepeatIterator(positions.begin());}
    RepeatIterator repeatEnd(){return RepeatIterator(positions.end());}
    SpacerIterator spacerBegin(){return SpacerIterator(positions.begin() + 1);}
    SpacerIterator spacerEnd(){return SpacerIterator(positions.end() - 1);}
protected:
    storage_t positions;
};

然后使用clang++ -std=c++0x -o testRepeatArray RepeatArray.cpp编译的tesing程序

int main() {
    RepeatArray r = RepeatArray();
    r.add(1,3);
    r.add(7,12);
    std::cout<<"original:"<<std::endl;
    r.dump();
    std::cout << "Testing Repeat iterator:"<<std::endl;
    for (RepeatArray::RepeatIterator it2 = r.repeatBegin(); it2 != r.repeatEnd(); ++it2) {
        std::cout << (*it2).first <<","<< (*it2).second << std::endl;
    }
    std::cout << "Testing Spacer iterator:"<<std::endl;
    for (RepeatArray::SpacerIterator it3 = r.spacerBegin(); it3 != r.spacerEnd(); ++it3) {
        std::cout << (*it3).first <<","<< (*it3).second << std::endl;
    }
    std::cout<<"Testing modification:"<<std::endl;
    RepeatArray::RepeatIterator it = r.repeatBegin();
    (*it).first = 0;
    (*it).second = 123;
    r.dump();
    return 0;
}