C++范围for循环通过begin()/end()迭代器遍历STL容器,简化代码并减少错误。它支持vector、list、map等容器,推荐使用const auto&避免拷贝,修改元素时用auto&,但禁止循环中增删元素以防迭代器失效。不同容器遍历时性能各异:vector连续内存高效,list链表跳转较慢,map按键排序访问,unordered_map无序哈希遍历。该机制统一了容器遍历接口,提升可读性与安全性。

C++的范围for循环(range-based for loop)与STL容器的结合,简直就是现代C++编程里的一股清流。它让遍历容器变得异常简洁、直观,并且在很大程度上减少了我们写出迭代器错误的机会。在我看来,这是C++11引入的最实用特性之一,它不仅提升了代码的可读性,更解放了我们的一部分心智负担,可以专注于业务逻辑而非繁琐的遍历细节。
使用C++范围for循环遍历STL容器非常直接。你只需要在
for
:
std::vector<int>
#include <vector>
#include <iostream>
#include <map>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
// 遍历并打印vector中的每个元素
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 如果需要修改元素,使用引用
for (int& num : numbers) {
num *= 2; // 将每个元素乘以2
}
// 再次打印修改后的vector
for (const int& num : numbers) { // 使用const引用避免不必要的拷贝和意外修改
std::cout << num << " ";
}
std::cout << std::endl;
std::map<std::string, int> ages = {
{"Alice", 30},
{"Bob", 24},
{"Charlie", 35}
};
// 遍历map,元素是std::pair<const std::string, int>
for (const auto&amp;amp;amp;amp; pair : ages) {
std::cout << pair.first << " is " << pair.second << " years old." << std::endl;
}
return 0;
}这种写法极大地简化了代码,避免了传统
for
很多人初次接触范围for循环时,会觉得它有点“魔法”。但实际上,它背后并没有什么黑科技,完全是基于C++标准库的迭代器概念实现的语法糖。编译器在处理范围for循环时,会将其“解糖”(desugar)成一个我们熟悉的、基于迭代器的传统
for
立即学习“C++免费学习笔记(深入)”;
具体来说,对于
for (declaration : expression)
expression
begin()
end()
expression
begin()
end()
// 假设 original_expression 是你的容器,比如 std::vector<int> numbers
{
auto&amp;& __range = original_expression; // 获取容器的引用
auto __begin = __range.begin(); // 获取起始迭代器
auto __end = __range.end(); // 获取结束迭代器
for (; __begin != __end; ++__begin) { // 传统的迭代器循环
declaration = *__begin; // 解引用迭代器,将值赋给声明的变量
// 你的循环体代码
}
}这里的
__range
__begin
__end
declaration
*__begin
int num
int& num
num
const int& num
这种内部机制确保了范围for循环与STL容器的完美兼容性,因为它本质上就是在使用容器提供的迭代器接口。任何满足“迭代器概念”的类型,只要提供了
begin()
end()
std::begin
std::end
std::vector
std::list
std::map
尽管范围for循环非常方便,但要用好它,还是有一些值得注意的最佳实践和陷阱:
const auto&amp;amp;amp;
const auto&amp;amp;amp; element : container
std::vector<std::string> names = {"Alice", "Bob"};
for (const auto&amp;amp;amp; name : names) { // 推荐
std::cout << name << std::endl;
}auto&
const
auto& element : container
std::vector<int> scores = {10, 20, 30};
for (auto& score : scores) {
score += 5; // 直接修改容器中的元素
}begin()
end()
std::vector
std::vector<int> myVec = {1, 2, 3};
// 错误示范:在范围for循环中修改容器大小
// for (int x : myVec) {
// if (x == 2) {
// myVec.push_back(4); // 极可能导致未定义行为
// }
// }auto
auto
std::map
std::unordered_map
std::pair<const Key, Value>
for (auto& pair : myMap)
pair
std::pair<const Key, Value>&
for (auto& [key, value] : myMap)
const auto&amp;amp;amp;
auto&
int
char
for (int num : numbers)
const auto&amp;amp;amp;
for
for (size_t i = 0; i < vec.size(); ++i)
std::iota
std::transform
begin()
end()
范围for循环的优势在于它提供了一个统一的接口来遍历所有符合要求的容器,但其底层行为和性能特点会因容器类型而异。
std::vector
std::deque
std::vector
std::deque
++__begin
std::vector<double> data = {1.1, 2.2, 3.3};
for (const auto&amp;amp;amp; val : data) {
std::cout << val << " ";
}
// 输出: 1.1 2.2 3.3std::list
std::list
++__begin
vector
list
std::list<char> chars = {'a', 'b', 'c'};
for (char c : chars) { // char是小类型,直接拷贝无妨
std::cout << c << " ";
}
// 输出: a b cstd::map
std::set
std::multimap
std::multiset
表现: 这些是基于平衡二叉搜索树实现的容器。它们的迭代器也是双向迭代器。遍历时,会按照键的排序顺序访问元素。
++__begin
vector
list
元素类型: 对于
std::map<Key, Value>
std::pair<const Key, Value>
Key
const
示例:
std::map<std::string, int> scores = {{"Zoe", 90}, {"Amy", 95}, {"Ben", 88}};
for (const auto&amp;amp;amp; entry : scores) { // entry是std::pair<const std::string, int>
std::cout << entry.first << ": " << entry.second << std::endl;
}
// 输出(按键排序):
// Amy: 95
// Ben: 88
// Zoe: 90
// C++17 结构化绑定
for (const auto&amp;amp;amp; [name, score] : scores) {
std::cout << name << " got " << score << std::endl;
}std::unordered_map
std::unordered_set
std::unordered_multimap
std::unordered_multiset
++__begin
std::unordered_map<Key, Value>
std::pair<const Key, Value>
std::unordered_set<std::string> fruits = {"apple", "banana", "orange"};
for (const std::string& fruit : fruits) {
std::cout << fruit << " ";
}
// 输出顺序不确定,可能是 "banana apple orange " 或其他总而言之,范围for循环提供了一个统一且高可读性的接口,隐藏了不同容器类型迭代器的具体实现细节。这使得我们能够以一致的方式处理各种STL容器,而无需关心其底层是连续内存、链表节点还是树节点。当然,作为一名C++开发者,理解这些底层差异对于性能优化和避免潜在陷阱依然至关重要。
以上就是C++范围for循环与STL容器结合使用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号