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();
}