(Please note the edit below)
The for-range loop does not give you access to the internal iterator. On one hand, this is good because you can't mess with it. On the other hand this might be bad because you need the iterator to know where you are in the container. So, we can't use a for-range loop as outer loop unless you iterate over something with a linear memory layout where you can take the address of an item as an iterator.
Also, the standard library is not yet up to the task of dealing with ranges in a convenient way. I'm using some utilities from Boost like iterator_range
for this code snippet:
using boost::make_iterator_range;
using std::next;
for (auto iter1 = container.begin(), ee = container.end(); iter1 != ee; ++iter1) {
auto& item1 = *iter1;
for (auto& item2 : make_iterator_range(next(iter1),ee)) {
// do something with item1 and item2
}
}
Admittedly, not very pretty. But this shows one way how you can use the for-range loop given a pair of iterators. Basically, the for-range loop eats anything that offers begin/end functions. make_iterator_range
wraps a pair of iterators and returns something, that provides begin/end functions.
Edit: I recently learned that boost::irange
can also produce sequences of iterators (and not just sequences of numbers). With that in mind, check out this program:
#include <iostream>
#include <vector>
#include <boost/range/irange.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/adaptor/indexed.hpp>
int main()
{
using std::vector;
using std::next;
using boost::irange;
using boost::make_iterator_range;
namespace ba = boost::adaptors;
vector<double> x {1.1, 2.2, 3.3, 4.4, 5.5, 6.6};
for (auto iter1 : irange(begin(x),end(x))) {
auto& item1 = *iter1;
for (auto& item2 : make_iterator_range(next(iter1),end(x))) {
// do something with item1 and item2
std::cout << item1 << " < " << item2 << std::endl;
}
}
return 0;
}
I tested this with G++ 4.6.3 in C++0x mode and Boost 1.48 and it actually works.