c++20 中不存在 std::ranges::next,正确用法是 std::next(c++11 起)获取新迭代器副本,或 std::ranges::advance(c++20)就地修改迭代器;前者要求前向迭代器以上,后者返回 void 且不生成新迭代器。

std::ranges::next 是 C++20 引入的,但实际不能直接用
你写 std::ranges::next 会编译失败——它根本不存在。C++20 的 <iterator></iterator> 里只有 std::next(在 std:: 命名空间),而 std::ranges 命名空间下没有 next。这是常见误解,源于把 std::ranges::advance 和旧式 std::next 混淆了。
真正可用的是:
-
std::next:标准库老成员,C++11 就有,适用于所有前向迭代器及以上 -
std::ranges::advance:C++20 新增,就地修改迭代器,不返回新副本
用 std::next 获取后继迭代器的正确写法
std::next 接收一个迭代器和可选步数(默认为 1),返回移动后的新迭代器(原迭代器不变)。它要求迭代器至少满足 ForwardIterator 概念。
示例:
std::vector<int> v = {10, 20, 30};
auto it = v.begin();
auto next_it = std::next(it); // 指向 20
auto next2_it = std::next(it, 2); // 指向 30
</int>
注意:
- 对
std::list::iterator或std::vector::iterator都适用 - 若步数过大(如超出容器范围),行为未定义——不会抛异常,也不会检查边界
- 不要对
std::istream_iterator等输入迭代器用std::next,它们不满足前向迭代器要求
为什么不用 std::ranges::advance 替代 next?
std::ranges::advance 修改传入的迭代器本身,且返回 void(C++20)或步数余量(C++23 起有重载)。它不提供“获取新迭代器”的能力。
比如:
auto it = v.begin(); std::ranges::advance(it, 2); // it 被修改为指向 30,无返回值 // 没法写成 auto new_it = std::ranges::advance(it, 2);
如果你需要保持原迭代器不变,又想走 ranges 风格,只能手动复制再 advance:
auto it = v.begin(); auto new_it = it; std::ranges::advance(new_it, 2);
这比直接用 std::next(it, 2) 多一次赋值,没优势。
容易踩的坑:随机访问迭代器 vs 普通前向迭代器
std::next 对不同迭代器类型性能差异极大:
- 对
std::vector、std::string等的迭代器(随机访问),std::next(it, n)是 O(1) - 对
std::list、std::forward_list的迭代器(仅前向),它是 O(n),逐个++it
如果在性能敏感路径里对 list 迭代器反复调用 std::next(it, 1000),就会明显拖慢。此时应考虑改用索引结构,或确认是否真需要跳转而非遍历。
另外,别在 constexpr 上下文中依赖 std::next——它不是字面量函数(C++20 中仍非 constexpr),无法用于编译期计算。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











