Question: Suppose I have a sorted vector without duplicated values. If I want to go through all the triples of different values, I do this:

```
for(std::size_t i = 0; i < data.size(); ++i)
  for(std::size_t j = i+1; j < data.size(); ++j)
    for(std::size_t k = j+1; k < data.size(); ++k)
      do_somthing_with(data[i],data[j],data[k]);

```

**How can I do that with iterators if my container is a `std::set` ?**

*Note: I don't use C++11 for compatibility reasons.*

Answer: 
You can do pretty much the same as with the vector, but you'll need to create a wrapper function, that will copy and increment set iterator:

```
std::set<int>::const_iterator next_iterator(std::set<int>::const_iterator it)
{
  return ++it; // it has been passed by value, so already copied
}

//...

for (std::set<int>::const_iterator it = data.begin(); it != data.end(); ++it)
  for(std::set<int>::const_iterator jt = next_iterator(it); jt != data.end(); ++jt)
    for(std::set<int>::const_iterator kt = next_iterator(jt); kt != data.end(); ++kt)
       // ...

```
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](https://en.cppreference.com/w/cpp/iterator/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](https://en.cppreference.com/w/cpp/iterator/next#Possible_implementation).

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);

```