编写一个使多个容器看起来像一个的迭代器

2022-01-10 00:00:00 iterator c++ boost

考虑以下简化示例和所需的输出:

Consider the following simplified example and desired output:

class A
{
    class combined_iterator
    {
        ????
    }
    typedef ??? t_combined_it;

    t_combined_it begin();
    t_combined_it end();

    std::vector<int> m_Vec1, m_Vect2;
}

A a;
a.m_Vec1.push_back(1);
a.m_Vec2.push_back(2);
for (A::t_combined_it it = a.begin() ; it != a.end() ; it++) {
     std::cout << *it << " ";
}

输出:

1 2 

我认为这个问题很清楚:我如何编写一个迭代器,使它看起来好像两个或多个其他迭代器实际上只是一个序列.因此,在示例中,我可以使用一个迭代器,它首先迭代 m_Vec1 的元素,然后是 m_Vec2 的元素,而不是迭代 m_Vec1 和 m_Vec2.

I think the question is clear from this: how do I write an iterator that makes it look as if two or more other iterators are really just one sequence. So that, in the example, instead of iteration over both m_Vec1 and m_Vec2, I can use an iterator that iterates over first the elements of m_Vec1 and then m_Vec2, transparently.

我发现了以下问题,我认为它提出了相同的问题:制作一个 c++遍历 2 个容器的迭代器.这个问题没有好的答案;原始提问者提出的解决方案似乎很复杂,而且(相对)占用大量内存.

I found the following question which I think asks the same: Make a c++ iterator that traverses 2 containers . There were no good answers to this question; the solution presented by the original asker seems convoluted, and it is (relatively) memory-intensive.

我尝试了一种简单的方法,将 std::vector::iterator 保留为我的自定义迭代器的成员,并将其与被迭代的每个序列的 .end() 迭代器进行比较;然而,比较来自不同容器的迭代器似乎是非法的(我希望它们只是返回不相等" - 也许这是寻找解决这个问题的方向?我想不出如何不过要实现它).

I tried a naive approach by keeping a std::vector::iterator as a member of my custom iterator, and comparing it to the .end() iterators of each of the sequences being iterated over; however it seems that it is illegal to compare iterators from different containers (where I would have preferred them just to return 'not equal' - maybe that is a direction to go for finding the solution to this problem? I can't think of how to implement it, though).

在可能且相关的情况下,我想使用 boost::iterators,就像我在其他地方使用它们一样,我喜欢它为我的迭代器实现提供的同质性;但当然,如果有人有想法但不使用它们,我可以自己实现它们,所以从这个意义上说,它们不是必需的.

Where possible and if relevant, I would like to use boost::iterators as I use them elsewhere and I like the homogeneity it provides to my iterator implementations; but of course if someone has an idea without using them, I can work them in myself, so they're not required in that sense.

推荐答案

boost::join 是您正在寻找的.您还可以研究实现,尤其是如何推导容器遍历、引用和返回值类型的最小公分母.引用:

boost::join is what you're looking for. You can also study the implementation, especially how to derive the lowest common denominator for container traversal, reference and return value types. To quote:

连接函数的目的是将两个范围连接成一个较长的范围.

The intention of the join function is to join two ranges into one longer range.

生成的范围将具有作为参数提供的两个范围中最低的公共遍历.

The resultant range will have the lowest common traversal of the two ranges supplied as parameters.

请注意,由于在遍历期间需要检查范围的末尾是否已到达内部,因此连接的范围会产生性能成本.

Note that the joined range incurs a performance cost due to the need to check if the end of a range > has been reached internally during traversal.

相关文章