std::distance 计算两迭代器间元素个数,随机访问迭代器下为 O(1),否则 O(n);std::advance 将迭代器移动指定距离,同样依迭代器类型决定效率,二者均需确保操作合法以避免未定义行为。
在C++ STL中,distance 和 advance 是两个用于操作迭代器的实用函数,常用于计算或调整容器中元素的位置。它们定义在 iterator 头文件中(#include <iterator>),适用于不同类型的迭代器,但行为受迭代器类别的影响。
distance:计算两个迭代器之间的距离
std::distance(first, last) 返回从迭代器 first 到 last 之间的元素个数,即位置差。
返回类型是 std::iterator_traits<Iterator>::difference_type,通常是 ptrdiff_t。
注意:
立即学习“C++免费学习笔记(深入)”;
- 要求 first 和 last 属于同一容器,且 first 可到达 last(即 last 在 first 之后或相等)。
- 对随机访问迭代器(如 vector、array),计算是 O(1) 的,直接用减法:
last - first
。
- 对双向或前向迭代器(如 list、forward_list),需要逐个移动迭代器,时间复杂度为 O(n)。
示例:
#include <vector> #include <iterator> #include <iostream> <p>std::vector<int> vec = {10, 20, 30, 40, 50}; auto it1 = vec.begin(); auto it2 = vec.begin() + 3;</p><p>std::cout << std::distance(it1, it2) << std::endl; // 输出 3
advance:将迭代器向前或向后移动指定距离
std::advance(it, n) 将迭代器 it 原地移动 n 个位置。
- 若 n 为正,向前移动;n 为负,向后移动(需支持双向移动)。
- 不返回新迭代器,而是直接修改传入的迭代器。
注意:
立即学习“C++免费学习笔记(深入)”;
- 对随机访问迭代器,O(1) 时间完成(直接加减)。
- 对前向或双向迭代器,O(n) 时间,逐个递增或递减。
- 不能对输入迭代器使用负数 n,否则行为未定义。
示例:
#include <list> #include <iterator> <p>std::list<int> lst = {1, 2, 3, 4, 5}; auto it = lst.begin(); std::advance(it, 2); // it 指向第3个元素(值为3)</p><p>std::advance(it, -1); // 支持双向迭代器,向前移动1位
实际使用建议
在编写泛型代码时,合理使用 distance 和 advance 可以让算法兼容多种容器。
- 避免对非随机访问迭代器频繁调用 distance,性能较差。
- 使用 advance 时确保迭代器不会越界,否则未定义行为。
- 若需获取移动后的新迭代器而不改变原值,可手动实现或使用 std::next 和 std::prev。
基本上就这些。理解这两个函数的行为差异,有助于写出高效且可移植的 STL 代码。