【问题标题】:How to use `boost::range` iterators with standard iterators如何将 `boost::range` 迭代器与标准迭代器一起使用
【发布时间】:2019-08-09 22:00:56
【问题描述】:

我有接受 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,如何传递非常量左值引用?

例如:

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 iterator std boost-range


    【解决方案1】:

    您应该强烈考虑使用模板。这样做让编译器保留有关实际发生的操作的有用信息,这极大地帮助它生成优化的输出。 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 &amp; int *&amp; 更少。几乎总是按值传递是正确的行为。复制起来很便宜,因为它包含来自构造它的 Rangebeginend 迭代器,仅此而已。

    【讨论】:

      【解决方案2】:

      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;
      

      【讨论】:

      • 谢谢!是的,我相信这就是我正在寻找的。但是有没有办法访问范围的size?似乎 size 对于 boost::any_range&lt;Point, boost::bidirectional_traversal_tag, Point, std::ptrdiff_t&gt; 是未定义的;
      • 您可以使用免费功能boost::size
      • 只需致电boost::size(range)
      • 谢谢!有没有办法传递非常量左值引用? (见上面的编辑)
      • @Anakhand 它比 boost::range 更像是一个 c++ 东西——除非你的向量是范围类型(​​即继承),否则这是不可能的——你需要以某种方式创建范围对象,即是删除引用 - 我喜欢将范围视为一对迭代器。
      猜你喜欢
      • 2013-03-14
      • 1970-01-01
      • 2016-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多