Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a function that has a boost::Range as parameter?

Tags:

c++

boost

Is this a good way to implement my own functions (e.g. DoSomethingWithRange) that accept a boost range as a parameter?

#include <iostream>
#include <vector>
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>

using namespace std;

template <typename RangeType>
    void DoSomethingWithRange(const RangeType &range)
{
    typename RangeType::const_iterator beginIt = boost::begin(range);
    typename RangeType::const_iterator endIt = boost::end(range);

    for(typename RangeType::const_iterator it = beginIt; it != endIt; ++it)
    {
        cout << *it << endl;
    }
}

bool IsPos(int i)
{
    return i>0;
}

int main(int , char** )
{
    vector<int> test;

    test.push_back(1);
    test.push_back(-1);

    DoSomethingWithRange(test | boost::adaptors::filtered(IsPos));
}
like image 708
nabulke Avatar asked Feb 29 '12 15:02

nabulke


1 Answers

This won't work with normal arrays, because RangeType::const_iterator won't be defined. It also won't work when passing in std::pair<iterator,iterator>, which is supported by Boost.Range as well.

Instead, you should use boost::range_iterator<const RangeType>::type. This will work with all types supported by Boost.Range: normal iterable objects, arrays, and iterator pairs.

Example:

template <typename RangeType>
void DoSomethingWithRange(const RangeType &range)
{
    typedef typename boost::range_iterator<const RangeType>::type const_iterator;
    const_iterator endIt = boost::end(range);
    for(const_iterator it = boost::begin(range); it != endIt; ++it)
        cout << *it << endl;
}

int main(int, char** )
{
    vector<int> test;
    test.push_back(1);
    test.push_back(-1);
    DoSomethingWithRange(test);

    int test2[] = {12,34};
    DoSomethingWithRange(test2);

    std::pair<int*,int*> test3(test2, test2+1);
    DoSomethingWithRange(test3);
}
like image 90
interjay Avatar answered Oct 13 '22 00:10

interjay