在 C++ 中迭代集合

Iterating over sets in c++

要么是我瞎了,要么是 std::set 在重载输出运算符时的行为与 std::vector 有很大不同。考虑下面的代码。

#include <set>
#include <iostream>

std::ostream& operator<<(std::ostream& os, const std::set<int>& myset) {
    for (std::set<int>::const_iterator it = myset.begin(); it < myset.end(); ++it) {
        os << *it;
        return os;
    }
}

int main () {}

如果在两个地方将 std::set 替换为 std::vector 并在包含中将 <set> 替换为 <vector>,则代码将按预期工作。区别在哪里?我的编译器 (g++) 给出了如下奇怪的错误消息。

/usr/include/c++/4.8/bits/stl_iterator.h:297:5: note: template argument deduction/substitution failed:

因此,即使我明确告诉我正在使用 std::set<int>,它也会以某种方式失败,并且这种行为只发生在 std::set 上。

要在这两种情况下工作,您的循环应该是:

for (std::set<int>::const_iterator it = myset.begin(); it != myset.end(); ++it)

it < myset.end() 仅适用于随机访问迭代器,其中 std::set::iterator 是双向的。

Here you can read what bidirectional iterator provides vs random access one

你的循环条件是错误的it < myset.end();std::set::iterator 不能与 < 运算符进行比较,因为它不是随机访问迭代器。 this sample 中的错误消息更清楚。

要修复,请使用 != 运算符进行比较:

#include <set>
#include <iostream>

std::ostream& operator<<(std::ostream& os, const std::set<int>& myset) {
    for (std::set<int>::const_iterator it = myset.begin(); it !=  myset.end(); ++it) {
                                                           // ^^
        os << *it;
    }
    return os;
}

int main () {}

Working Demo


顺便说一句,您的样本中的 for 循环体缺少 }

将循环更改为

后您的代码构建良好
for (std::set<int>::const_iterator it = myset.begin(); it != myset.end(); ++it)

请注意,一般来说,您不能假设您可以小于比较迭代器。

一些容器的迭代器可能支持这个(这也可能取决于实现),但你真的不应该依赖这个。