c – 使用带有类型擦除的reverse_iterator

我有一个包含和管理一系列对象的类.为了避免在允许迭代这些对象时泄漏这些对象的方式,我决定使用boost :: any_iterator来使用类型擦除.

 using my_erased_type_iterator = boost::range_detail::any_iterator<
    MyClass,
    boost::bidirectional_traversal_tag,
    MyClass&, 
    std::ptrdiff_t>;

我在MyClass中定义了一个函数Begin()和End(),它只是将容器的begin()和end()函数作为my_erased_type_iterator返回.它完全按照我的意愿工作,MyClass之外的任何人都不知道我正在使用向量来存储对象,除了我在Myclass接口中公开的函数之外,他们还可以访问容器.

现在,由于多种原因,我需要反向迭代对象.我还需要知道反向迭代器之后的下一个元素(类似于在普通迭代器上调用std :: next(),对于反向迭代器来说已经不是那么简单了)我可能还需要调用像erase()这样的函数反转迭代器.

所以对于我的问题:是否有一种优雅的方式来使用类型擦除和反向迭代器(以及正向和反向的const版本)?我应该使用正向类型擦除迭代器并反向迭代吗?我想到我可能会以错误的方式解决这个问题,所以我愿意接受任何建议或者在需要时澄清我的问题.

最佳答案 请注意,any_iterator是一个实现细节.

我会首先回答你的直接问题,然后用any_range<>来显示方法.正如Boost Range的公共API所预期的那样.

make_reverse_iterator

您只需使用make_reverse_iterator工具即可

>标准c 14 http://en.cppreference.com/w/cpp/iterator/make_reverse_iterator
>提升http://www.boost.org/doc/libs/1_60_0/libs/iterator/doc/reverse_iterator.html

Live On Coliru

#include <boost/range.hpp>
#include <boost/range/any_range.hpp>

struct MyClass {
    int i;
};

using my_erased_type_iterator = boost::range_detail::any_iterator<
    MyClass,
    boost::bidirectional_traversal_tag,
    MyClass&, 
    std::ptrdiff_t>;

#include <iostream>
#include <vector>

int main() {
    using namespace boost;
    std::vector<MyClass> const v { {1}, {2}, {3}, {4} };

    for (auto& mc : make_iterator_range(
                make_reverse_iterator(v.end()),
                make_reverse_iterator(v.begin())))
    {
        std::cout << mc.i << " ";
    }
}

打印

4 3 2 1 

2.反转范围适配器:

或者,您可以使用全范围风格并使用any_range<>:

Live On Coliru

int main() {
    std::vector<MyClass> const v { {1}, {2}, {3}, {4} };

    boost::any_range_type_generator<decltype(v)>::type x = reverse(v);

    for (my_erased_type_const_iterator f = boost::begin(x), l = boost::end(x); f!=l; ++f) {
        std::cout << f->i << " ";
    }

}
点赞