2012-06-15 4 views
2

iterator_range를 만들고 보유하고 싶습니다. 범위는 술어에 기초하여 생성됩니다 (이 예제에서는 짝수를 찾습니다).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(); 
} 

답변

4
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.을 사용할 수 있습니다. 이름에서 알 수 있듯이 특정 유형의 모든 범위를 저장할 수 있습니다.

또한 make_filter_iterator 대신 boost::adaptors::filtered과 같은 proper Boost range-adapters을 사용하는 것이 좋습니다.

+0

빠른 답장을 보내 주셔서 감사합니다. 나는 '자동'과 BOOST_AUTO를 시도했다. 둘 다 작동합니다. 나는 최고의 BOOST 사용법을 배울 것이 많다. Windows와 Mac 모두를 위해 빌드 할 때마다 문제가 발생하지 않도록해야하기 때문에 조금 더 복잡합니다. 다시 한번 귀하의 도움에 감사드립니다. – rcohn

+0

@rcohn :이 질문에 대한 답변이있는 경우 녹색 확인 표시를 클릭하여 대답을 수락하십시오. –

+0

확인. 나는 그것을 클릭했다. 그 일을 알지 못해서 사과드립니다. 이것은 나의 첫번째 게시이었다. – rcohn