我有一个包含和管理一系列对象的类.为了避免在允许迭代这些对象时泄漏这些对象的方式,我决定使用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
#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<>:
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 << " ";
}
}