如何将“boost::range”迭代器与标准迭代器一起使用

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

提问人:Anakhand 提问时间:3/19/2019 最后编辑:Anakhand 更新时间:3/19/2019 访问量:2066

问:

我有接受迭代器的函数,如std::vector

typedef std::vector<Point> Points;

Points ConvexHull(Points::const_iterator first, Points::const_iterator last);

我通常会将迭代器传递给他们,但偶尔我需要使用迭代器,例如 的范围迭代器。我应该如何更改函数的参数化,最好没有模板,以便它们接受两个迭代器?此外,如何在每种类型中指示我需要哪些迭代器概念?stdboostboost::join

我尝试查看文档,但这对我来说非常混乱,我不知道从哪里开始。boost::range

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


编辑:

如果我使用 ,如何传递非常量左值引用?boost::any_range

例如:

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
C++ Boost 迭代器 std boost-range

评论


答:

4赞 darune 3/19/2019 #1

具有用于此目的的功能,它适合您的情况。any_range

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

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

#include <boost/range/any_range.hpp>

typedef boost::any_range<Point,
                         boost::bidirectional_traversal_tag,
                         Point,
                         std::ptrdiff_t
                        > PointRange;

评论

0赞 Anakhand 3/19/2019
谢谢!是的,我相信这就是我要找的。但是有没有办法进入这个范围?它似乎是未定义的sizesizeboost::any_range<Point, boost::bidirectional_traversal_tag, Point, std::ptrdiff_t>;
2赞 Caleth 3/19/2019
您可以使用免费功能boost::size
1赞 darune 3/19/2019
只需致电boost::size(range)
0赞 Anakhand 3/19/2019
谢谢!有没有办法传递非常量左值引用?(见上面的编辑)
1赞 darune 3/19/2019
@Anakhand它更像是 C++ 而不是 boost::range 的东西 - 这是不可能的,除非你的向量是范围类型(即继承) - 你需要以某种方式创建 range 对象,即删除引用 - 我喜欢将范围视为一对迭代器。
1赞 Caleth 3/19/2019 #2

您应该强烈考虑使用模板。这样一来,编译器就可以保留有关实际发生的操作的有用信息,这极大地有助于它生成优化的输出。约定是为所需的概念命名类型参数。F.D.公司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;

可能需要比 .几乎总是按值传递是正确的行为。复制起来很便宜,因为它包含构建它的范围中的一个和迭代器,仅此而已。PointRange &int *&beginend