std::iota

来自cppreference.com
< cpp‎ | algorithm
 
 
算法库
受约束算法及范围上的算法 (C++20)
包含算法例如 ranges::copy, ranges::sort, ...
执行策略 (C++17)
排序和相关操作
划分操作
排序操作
二分搜索操作(在已划分范围上)
集合操作(在有序范围上)
归并操作(在有序范围上)
堆操作
最小/最大操作
(C++11)
(C++17)
字典序比较操作
排列操作
C 库

数值运算
iota
(C++11)                       
在未初始化内存上的操作
 
 
在标头 <numeric> 定义
template< class ForwardIt, class T >
void iota( ForwardIt first, ForwardIt last, T value );
(C++11 起)
(C++20 起为 constexpr)

以始于 value 并重复地求值 ++value 的顺序递增值填充范围 [firstlast)

等价操作(假设 ++value 会返回自增后的值):

*first   = value;
*++first = ++value;
*++first = ++value;
*++first = ++value;
// 抵达 “last” 前重复

如果满足以下任意条件,那么程序非良构:

  • T 不可转换到 ForwardIt值类型
  • 表达式 ++val 非良构,其中 valT 类型变量。

参数

first, last - value 开始按顺序递增的值所填充的范围
value - 要存储的初始值

复杂度

自增与赋值 std::distance(first, last) 次。

可能的实现

template<class ForwardIt, class T>
constexpr // C++20 起
void iota(ForwardIt first, ForwardIt last, T value)
{
    for (; first != last; ++first, ++value)
        *first = value;
}

注解

此函数命名来源于编程语言 APL 中的整数函数 。它是 C++98 所不曾包含的 STL 组件之一,但最终在 C++11 进入了标准库。

示例

下列代码应用 std::shufflestd::list 的迭代器组成的 vector,因为不能直接应用 std::shufflestd::list。用 std::iota 填充两个容器。

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <list>
#include <numeric>
#include <random>
#include <vector>
 
class BigData // 复制操作低效
{
    int data[1024]; /* 一些原始数据 */
public:
    explicit BigData(int i = 0) { data[0] = i; /* ... */ }
    operator int() const { return data[0]; }
    BigData& operator=(int i) { data[0] = i; return *this; }
    /* ... */
};
 
int main()
{
    std::list<BigData> l(10);
    std::iota(l.begin(), l.end(), -4);
 
    std::vector<std::list<BigData>::iterator> v(l.size());
    std::iota(v.begin(), v.end(), l.begin());
    // 用(指向原数据的)迭代器的向量来避免昂贵复制操作,
    // 也是因为无法直接对 std::list 应用 std::shuffle(见下)
 
    std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});
 
    std::cout << "list l 原来的内容:\t\t";
    for (const auto& n : l)
        std::cout << std::setw(2) << n << ' ';
    std::cout << '\n';
 
    std::cout << "通过打乱的 v 看到的 l 的内容:\t";
    for (const auto i : v)
        std::cout << std::setw(2) << *i << ' ';
    std::cout << '\n';
}

可能的输出:

list l 原来的内容:		-4 -3 -2 -1  0  1  2  3  4  5
通过打乱的 v 看到的 l 的内容:	-1  5 -4  0  2  1  4 -2  3 -3

参阅

由通过重复对某个初值自增所生成的序列组成的 view
(类模板) (定制点对象)
将一个给定值复制赋值给一个范围内的每个元素
(函数模板)
以特定值向范围的各元素赋值
(niebloid)
将相继的函数调用结果赋值给一个范围中的每个元素
(函数模板)
保存函数结果到一个范围中
(niebloid)
用从起始值开始连续递增的值填充一个范围
(niebloid)