如何将 `boost::range` 迭代器与标准迭代器一起使用
How to use `boost::range` iterators with standard iterators
我有接受 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_interface
和 boost::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
boost-range 具有用于此目的的 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;
您应该强烈考虑使用模板。这样做让编译器保留有关实际发生的操作的有用信息,这极大地帮助它生成优化的输出。 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 *&
更少 。几乎总是按值传递是正确的行为。复制起来很便宜,因为它拥有 Range 中的 begin
和 end
迭代器,仅此而已。
我有接受 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_interface
和 boost::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
boost-range 具有用于此目的的 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;
您应该强烈考虑使用模板。这样做让编译器保留有关实际发生的操作的有用信息,这极大地帮助它生成优化的输出。 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 *&
更少 。几乎总是按值传递是正确的行为。复制起来很便宜,因为它拥有 Range 中的 begin
和 end
迭代器,仅此而已。