Monthly Archives: April 2013

Range based for loops and pairs of iterators

In C++11, we now have range-based for loops. Given a container c, it is easy to write:

    for ( auto x : c ) { do something with x }

but the STL deals in pairs of iterators.
Given two iterators, f and l, I still have to write:

    for ( auto it=f; it != l; ++it ) { do something with *it }
  • The first time I typed that, I got it wrong – I put a ‘,’ instead of the second ‘;’
  • The second time I wrote that, I got it wrong again! – I used it < l instead of it != l.

Anyway, I would like to be able to write something like:

    for ( auto x : f,l ) { do something with x }

But there is no support for that in C++11.

Enter iterator_pair:

    template <typename Iterator>
    class iterator_pair {
    public:
        iterator_pair ( Iterator first, Iterator last ) : f_ (first), l_ (last) {}
        Iterator begin () const { return f_; }
        Iterator end   () const { return l_; }

    private:
        Iterator f_;
        Iterator l_;
    };

With this I can now write:

    for ( auto x : iterator_pair<type of f and l> ( f,l )) { do something with x }

which works, but is still annoying. Why should I have to put the type of the iterators there in my for loop? Worse than that, if this is in a template, I may not know what the type of f and l are!

But a helper function makes it all better:

    template <typename Iterator>
    iterator_pair<Iterator> make_iterator_pair ( Iterator f, Iterator l ) {
        return iterator_pair<Iterator> ( f, l );
    }

Now my code looks like I want:

    for ( auto x : make_iterator_pair ( f,l )) { do something with x }

and I’m happy (for now).

I’m pretty sure that there’s a better name for this, but I’m going with iterator_pair for the moment.

Advertisements