如何归还iterator_range

How to return an iterator_range

本文关键字:iterator range 归还 何归还      更新时间:2023-10-16

我想创建并保留一个iterator_range。 范围是基于谓词构造的(在本例中,我寻找偶数)。

我可以这样做,但似乎我必须从正在迭代的基础向量中复制元素。

请在下面的示例中查找标记为">>>"的评论。

有没有办法创建iterator_range而不必从原始向量创建重复的条目?

我看了看,但没有看到,对这种特殊情况的答案。

#include <vector>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <boost/foreach.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range/iterator_range.hpp>
using namespace std; 
using namespace boost; 
typedef boost::iterator_range<vector<int>::iterator> int_range;
template< class Range, class Pred >
boost::iterator_range< boost::filter_iterator< Pred, typename boost::range_iterator<Range>::type > > 
make_filter_range( Range& rng, Pred pred ) {
    return boost::make_iterator_range( 
     boost::make_filter_iterator(pred, boost::begin(rng), boost::end(rng)), 
     boost::make_filter_iterator(pred, boost::end(rng), boost::end(rng)) );
}
// This is the predicate evaluation function.
bool IsEvenFilter(int val) { return val % 2 == 0; }
void TestMakeIteratorRange()
{
    std::vector<int> vals;
    vals.push_back(1);
    vals.push_back(4);
    vals.push_back(7);
    vals.push_back(11);
    vals.push_back(16);
    vals.push_back(19);
    vals.push_back(28);
    //>>> The following int_range line does not compile.  Why?
    //>>> How can I return an int_range?
    //>>> int_range intRange = make_filter_range( vals, boost::bind(&IsEvenFilter, _1));
    //>>> The following WILL work, but it forces a second copy of elements from vals.
    std::vector<int> v2 = boost::copy_range< std::vector<int> >( 
        make_filter_range( vals, boost::bind(&IsEvenFilter, _1)));
    int_range intRange = int_range(v2);
    // Dump out contents
    BOOST_FOREACH(int &val, intRange)
    {
        cout << " " << val;
    }
    cout << endl;
}
void main()
{
    TestMakeIteratorRange();
}
int_range intRange = make_filter_range( vals, boost::bind(&IsEvenFilter, _1));

您必须存储 make_filter_range 返回的类型。这不是int_range.

顺便说一下,这就是auto存在的原因(在 C++11 中);这样,如果你想存储函数返回的内容,就不必键入该返回值。如果您无权访问 C++11 auto ,请改用BOOST_AUTO

如果由于某种原因无法使用它,也可以使用 any_range .顾名思义,它可以存储特定类型的任何范围。

此外,请考虑使用适当的 Boost 范围适配器,例如 boost::adaptors::filtered 而不是 make_filter_iterator