如何使用标准迭代器使用`boost :: range`迭代器

How to use `boost::range` iterators with standard iterators

本文关键字:迭代器 boost range 何使用 标准      更新时间:2023-10-16

我具有 std::vector迭代器的功能,如

typedef std::vector<Point> Points;
Points ConvexHull(Points::const_iterator first, Points::const_iterator last);

我通常将std迭代器传递给它们,但有时我需要与boost迭代器一起工作,例如boost::join的范围迭代器。理想情况下,我应该如何更改功能的参数化,以便他们接受两个迭代器?此外,如何在每种类型中指出我需要的迭代概念?

我尝试查看boost::range文档,但这对我来说是压倒性的,我不知道从哪里开始。

例如,我找不到boost::range_details::any_forward_iterator_interfaceboost::range_details::any_forward_iterator_wrapper之间的区别,以及我是否应该使用其中任何一个来指定我需要一个前进迭代器。


编辑:

如果我使用boost::any_range,我该如何通过非const lvalue参考?

例如:

template<typename T>
using Range = boost::any_range<T, boost::random_access_traversal_tag, 
                               T, std::ptrdiff_t>;

f(Range<Point> &points);  // defined elsewhere
// -------------
vector<Point> vec;
f(vec);  // error; cannot bind non-const lvalue reference to unrelated type

Boost-range为此目的具有any_range,并且适合您的情况。

https://www.boost.org/doc/libs/1_60_0/libs/range/doc/html/range/Range/RANGE/RANGE/ranges/ranges/ranges/any_range.html

从您的示例中看起来像这样:

#include <boost/range/any_range.hpp>
typedef boost::any_range<Point,
                         boost::bidirectional_traversal_tag,
                         Point,
                         std::ptrdiff_t
                        > PointRange;

您应该强烈考虑使用模板。这样做,让我们保留有关实际发生哪些操作的有用信息,这极大地有助于其生成优化的输出。std::约定是为所需概念的类型参数命名。例如。

template< class BidirIt, class UnaryPredicate > // anything bidirectional (which includes random access)
BidirIt std::partition( BidirIt first, BidirIt last, UnaryPredicate p );

如果您真的不想要模板,则您仍然不应在detail名称空间中命名任何内容。像

#include <boost/range/any_range.hpp>
using PointRange = boost::any_range<Point, boost::random_access_traversal_tag>; // or another traversal tag.
using PointIterator = PointRange::iterator;

您可能需要比int *&少的PointRange & 。几乎总是按价值传递是正确的行为。复制价格便宜,因为它拥有beginend迭代器的 range ,而仅此而已。