std::iota是c++11引入的最简洁、零循环、无手动递增的填充方式,但要求目标容器预先分配足够空间;它仅写入不扩容,语义清晰且高效,适用于vector/Array等连续容器,不支持自定义步长,使用前须确保迭代器范围合法可写。

直接说结论: std::iota 是 C++11 引入的最简洁、零循环、无手动递增的填充方式,但必须确保目标容器已分配足够空间——它不扩容,只写入。
为什么用 std::iota 而不是 for 循环?
它把“从某值开始、逐个加 1、填满一段内存”的逻辑封装成单次调用,语义清晰、不易出错,且编译器通常能优化为高效内存写入(尤其对 std::vector 连续存储)。
常见误用是以为它会自动 resize() 容器,实际不会——传入的迭代器范围必须合法可写。
- 正确:先
vec.resize(n)或定义时指定大小,再调用std::iota(vec.begin(), vec.end(), start) - 错误:空
std::vector直接传begin()/end(),行为未定义 - 注意:
std::iota填充的是算术递增(+1),不能自定义步长;需要非 1 步长请用std::generate+ Lambda
std::iota 的参数和典型用法
函数原型是 template<class forwarditerator class t> void iota(ForwardIterator first, ForwardIterator last, T value);</class>,关键点:
立即学习“C++免费学习笔记(深入)”;
-
first和last必须构成有效左闭右开区间([first, last)),且first可写 -
value是起始值,类型需支持operator++(内置类型、满足要求的自定义类型均可) - 填充后,
*(first + i)等于value + i(i 从 0 开始)
示例:
std::vector<int> v(5); std::iota(v.begin(), v.end(), 10); // v 变为 {10, 11, 12, 13, 14}
对 std::array 同样适用:
std::array<char, 3> a; std::iota(a.begin(), a.end(), 'a'); // a 变为 {'a', 'b', 'c'}
容易踩的坑:迭代器失效与类型匹配
三个高频问题:
- 用
std::vector::data()配合std::iota?可以,但要自己算好长度:std::iota(arr, arr + n, 0)—— 注意别越界 - 起始值类型和容器元素类型不一致?比如
std::iota(v.begin(), v.end(), 0LL)填std::vector<int></int>,会隐式转换,但若溢出(如long long转char)则结果未定义 - 对
std::list使用?语法合法,但性能差(++迭代器是 O(1) 但遍历本身缓存不友好),不如用std::vector+std::iota+ 移动构造
真正要注意的是:它不检查目标是否可写,也不关心你传的是不是真迭代器。一旦 first 不可解引用或 last 不可达,就是未定义行为——调试时很难定位,务必在调用前确认容器 size 和迭代器有效性。