std::iota 是生成连续整数序列最轻量的方法,直接填充已分配空间的 std::vector;c++20 推荐使用 std::views::iota_view 实现惰性求值,语义最接近 python range。

用 std::iota 配合 std::vector 最快生成连续整数序列
Python 的 range(5) 本质是惰性生成器,但 C++ 没有原生等价物;若你只需要一次性拿到一串连续整数(比如用于循环索引或测试数据),std::iota 是最轻量、最直观的选择。
它不分配额外内存来“模拟”迭代器行为,而是直接填满已有容器:
std::vector<int> v(5);
std::iota(v.begin(), v.end(), 0); // v 变成 {0,1,2,3,4}</int>
-
std::iota要求容器已分配空间,不能对空vector直接调用begin()/end() - 起始值可以是任意整型或支持
operator++的类型(如long、char) - 性能上几乎无开销——就是一次顺序赋值,比手写
for循环还略快(因编译器易优化)
需要真正惰性遍历?自己写个简易 range_view 类
如果你在写算法模板、要传给 for (auto x : ...)、或内存极度敏感(比如嵌入式中不能预分配几百个 int),就得模拟 Python 的懒计算。C++20 有 std::ranges::iota_view,但老标准得手动封装。
一个最小可行的只读前闭后开 range(类似 range(start, stop, step))只需几十行:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
struct range {
int start, stop, step;
struct iter {
int val;
int operator*() const { return val; }
iter& operator++() { val += step; return *this; }
bool operator!=(const iter& o) const { return val != o.val; }
};
iter begin() const { return {start}; }
iter end() const { return {stop}; }
};
- 上面代码只支持正向、step > 0 场景;实际使用需判断
step符号并调整end()逻辑(比如val >= stop) - 没有边界检查:若
step为 0,begin() == end()就永远不成立,导致无限循环 - C++17 起可加
[[nodiscard]]提示用户别忽略返回值;C++20 后建议直接用std::ranges::iota_view<int></int>替代
std::ranges::iota_view 在 C++20 中怎么用
这是目前最接近 Python range 语义的标准方案,支持懒求值、可组合、能和 views::filter 等连用。
for (int i : std::views::iota(0, 5)) {
std::cout
-
std::views::iota(a, b)是前闭后开;std::views::iota(a)是无限序列,必须用take或take_while截断 - 不支持负步长(如
range(10, 0, -2)),得改用views::reverse+ 正向iota - 编译依赖
<ranges></ranges>和 C++20 模式;MSVC 19.30+、GCC 10.2+、Clang 13+ 支持完整特性
别踩坑:为什么不用 std::generate 或 lambda 模拟 range
有人试图用 std::generate + 捕获变量计数器来“生成” range,这看似灵活,实则危险且低效。
- lambda 捕获局部变量时若用引用(
[&i]),容器生命周期结束后的迭代器会访问悬垂引用 - 每次调用生成器都要修改外部状态,无法多线程安全复用
- 相比
iota或iota_view,多了函数调用开销和状态管理复杂度,纯属画蛇添足 - 更隐蔽的问题:某些 STL 实现对
generate的并行化优化不如iota稳定
真正需要动态逻辑(比如非线性序列)时,再考虑自定义 generator;对等差整数,就老实用 iota 或 iota_view。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










