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 might do something like:

```
if (data.size() < 2) { return; }

for (auto it1 = data.begin(); it1 != std::prev(data.end(), 2); ++it1) {
    for (std::size_t it2 = std::next(it1); it2 != std::prev(data.end()); ++it2) {
      for (std::size_t it3 = std::next(it2); it3 != data.end(); ++it3) {
          do_something_with(*it1, *it2, *it3);
      }
   }
}

```

You might cache value of `std::prev`.
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);

```