std::set 遍历所有对

std::set iterating over all pairs

考虑 code snippet 1:

#include <set>
#include <cstdio>

int main() {
    std::set<int> intset = {1, 2, 3, 4, 5, 6};
    for(std::set<int>::iterator it1 = intset.begin(); it1 != intset.end(); it1++)
      for(std::set<int>::iterator it2 = it1 + 1; it2 != intset.end(); it2++)
            printf("Pair {%d,%d}\n", *it1, *it2);
}

这不编译。参见 here

然而,我看不出这种遍历所有对的方式与 the accepted answer to the question here 有何不同。

从那里接受的答案转述,考虑 code snippet 2:

for (auto it1 = intset.begin(); it1 != intset.end(); ++it1) {
  for (auto it2 = it1; ++it2 != intset.end(); /**/) {
     printf("Pair {%d,%d}\n", *it1, *it2);
  }
}

我已经验证上面的代码确实可以正常工作。然而,code snippet 1 无法编译而上面的 code snippet 2 可以编译的根本原因是什么?

在这两种情况下,我们不只是增加一个集合迭代器吗?在一种情况下,我们正在做 it2 = it1 + 1,而在另一种情况下,我们正在做 ++it2.

it1 + 1是随机访问操作,所以要求迭代器是随机访问迭代器,由于std::set<int>::iterator不是随机访问迭代器,所以不支持这种操作。

++it2要求迭代器是正向迭代器,而std::set<int>::iterator由于是双向迭代器,所以是正向迭代器。