You can think of your problem as if you had to use iterators over indexes in your vector example. Let's simplify it that way:
for(std::size_t i = 0; i < data.size(); ++i)
do_somthing_with(data[i]);
You would write it like that with iterators:
for(std::vector<MyClass>::iterator it = data.begin(); it != data.end(); ++it)
do_somthing_with(*it);
Now it is straightforward to do the same with sets:
for(std::set<MyClass>::iterator it = data.begin(); it != data.end(); ++it)
do_somthing_with(*it);
If you want to use a triple-loop, in my opinion the problem is starting at the next iterator. With C++11 you could use std::next but since you can't, you need to store the iterator and then advance it:
for(std::set<MyClass>::iterator it1 = data.begin(); it1 != data.end(); ++it1)
{
std::set<MyClass>::iterator it2 = it1;
++it2;
for(; it2 != data.end(); ++it2)
{
std::set<MyClass>::iterator it3 = it2;
++it3;
for(; it3 != data.end(); ++it3)
do_somthing_with(*it1,*it2,*it3);
}
}
Alternately you can define your own next
function, e.g.:
template<class ForwardIt>
ForwardIt next(ForwardIt it)
{
return ++it;
}
This is basically a simplified version of the suggested implementation of std::next.
Then the code can be rewritten more easily:
for(std::set<MyClass>::iterator it1 = data.begin(); it1 != data.end(); ++it1)
for(std::set<MyClass>::iterator it2 = next(it1); it2 != data.end(); ++it2)
for(std::set<MyClass>::iterator it3 = next(it2); it3 != data.end(); ++it3)
do_somthing_with(*it1,*it2,*it3);