C++ 基于范围的for 循环 适用容器列举与分析

    技术2026-06-11  19

    C++ 11 基于范围的for 循环,使用起来特别方便,但是 是否所有容器均适合使用? 如何判断某个对象是否 支持 基于范围 的for 循环?

    基于范围 for循环,基本格式如下:

    XXX tempContainer; for (auto &item : tempContainer) { cout << item << endl; }

    这里的XXX 可以替换为任意的容器或者类类型,比如 map<int, int> tempContainer;

    - map类型

    int main() { std::map<int, int> tempMap{{1,2}, {5,4}, {2,3}}; for (auto &item : tempMap) { cout << item.first << " " << item.second << endl; } return 0; }

    输出结果:

    1 2 2 3 5 4

    输出结果是按照 key 值排序后输出的, 这里是因为使用的是map, 如果使用的是unordered_map, 则输出结果就是无序的,因为unordered_map使用的是hash存储,并不保证有序,而map 使用的是RB树,元素插入时是有序的。

    - set 类型

    int main() { set<int> temp{2, 3, 5, 2, 5}; for (auto &item : temp) { cout << item << endl; } cout << "set size:" << temp.size() << endl; return 0; }

    输出结果:

    2 3 5 set size:3

    set 对于重复的元素自动去重,使用set 容器的count(key) 函数可以快速判断set中是否包含元素key。

    - vector 类型

    int main() { vector<int> temp{1, 3, 2}; for (auto &item : temp) { cout << item << endl; } return 0; }

    输出结果:

    1 3 2

    - list类型

    int main() { list<int> temp{2,3,5}; for (auto &item : temp) { cout << item << endl; } return 0; }

    输出结果:

    2 3 5

    - stack类型

    int main() { stack<int> temp; temp.push(2); temp.push(2); for (auto &item : temp) { cout << item << endl; } return 0; }

    输出结果:

    F:\clion project\main.cpp: In function 'int main()': F:\clion project\main.cpp:71:23: error: no matching function for call to 'begin(std::stack<int>&)' for (auto &item : temp) { ^~~~

    - queue 类型

    int main() { queue<int> temp; temp.push(2); temp.push(3); for (auto &item : temp) { cout << item << endl; } return 0; }

    输出结果:

    F:\clion project\main.cpp: In function 'int main()': F:\clion project\main.cpp:72:23: error: no matching function for call to 'begin(std::queue<int>&)' for (auto &item : temp) {

    总结: 从上面的举例中可以看出:map, set, vector, list 都是支持 基于范围的 for 循环的; 但是stack, queue 不支持,且 报错信息是 无法匹配到 begin() 函数; 所以判断一个容器类型是否支持 基于范围 for循环,需要判断 该类型 是否 有自身的迭代器类型,同时提供begin(), end() 方法;因为 基于范围 for 循环本质 上就是 通过begin(), end()方法实现遍历。 关于 遍历过程中的修改 和 自定义的类实现 基于 范围的for 循环,可以参考如下博客: Range-Based-For

    Processed: 0.009, SQL: 10