三种遍历方法分别适用于哪些容器

C++ 中,遍历容器的方法与容器的特性有关。以下是三种遍历方法在不同容器中的适用情况:


1. 迭代器遍历

for (std::container_type<T>::iterator it = container.begin(); it != container.end(); ++it)
    std::cout << *it << std::endl;

适用容器

  • 所有标准容器,包括:

  • 顺序容器:std::vector, std::deque, std::list, std::array, std::forward_list

  • 关联容器:std::map, std::set, std::multimap, std::multiset

  • 无序容器:std::unordered_map, std::unordered_set, std::unordered_multimap, std::unordered_multiset

  • 自定义容器(只要实现了迭代器)。

原因

  • 迭代器是容器的通用接口,所有标准容器都支持迭代器遍历。

注意事项

  • 关联容器和无序容器的迭代器会返回键值对的类型(例如 std::pair<const Key, T>),需要通过 ->first->second 访问键和值。

  • 迭代器类型复杂,建议用 auto 替代显式声明。


2. 基于范围的循环(C++11及更高)

for (auto &element : container)
    std::cout << element << std::endl;

适用容器

  • 所有标准容器(与迭代器遍历一致)。

  • 支持 std::initializer_list

  • 支持范围类类型(只要提供 begin()end() 的成员或非成员函数)。

原因

  • 范围循环依赖容器的 begin()end() 方法,所有标准容器都实现了这些方法。

注意事项

  • 关联容器返回键值对 (std::pair<const Key, T>),需要用 element.firstelement.second 分别访问键和值。

  • 如果容器存储的是指针类型,使用 auto & 遍历避免浅拷贝。


3. 结构化绑定 + 基于范围的循环(C++17及更高)

for (auto &[key, value] : container)
    std::cout << key << ": " << value << std::endl;

适用容器

  • 关联容器std::map, std::multimap, std::unordered_map, std::unordered_multimap)。

  • 其他返回结构类型的容器(如元组、键值对)。

原因

  • 结构化绑定将容器元素解构为多个独立变量,适用于键值对类型的容器(例如 std::pair 或元组)。

注意事项

  • 不适用于只存储单值类型的容器(例如 std::vector, std::list)。

  • 对于非键值对容器,结构化绑定会导致编译错误。


总结:容器支持情况对比

最佳实践

  1. 简单遍历

  • 对于单值类型的容器(如 std::vectorstd::list),使用范围循环简洁高效。

  1. 键值对容器

  • 对于键值对类型(如 std::map),优先使用结构化绑定,更具可读性。

  1. 需要兼容性

  • 如果需兼容旧标准(如 C++98/03),使用显式迭代器遍历。