有些时候,我们急需用一段递增序列来初始化容器。这时候,我们可能会首先想起 std::fill, 但如果真正熟悉这个函数,会知道这货也就能用一个单一数值填满你的容器。或许你开始一筹莫展,决定土办法,一个循环,push 递增。

C++ 11 里有一个比较低调的方法可以一句话实现这个需求。即 std::iota.

好了,小二,赶紧上一盘递增序列。

cpp#include <numeric>

std::vector<int> ivec(10);
std::iota(ivec.begin(), ivec.end(), 0);
// ivec: 0,1,2,3,4,5,6,7,8,9

// 这个递增可不止局限于数值哟
std::vector<std::vector<int>::iterator> iter_vec(ivec.size());
std::iota(iter_vec.begin(), iter_vec.end(), ivec.begin());

for (auto it : iter_vec)
    std::cout << *it << " ";
// out: 0,1,2,3,4,5,6,7,8,9

实现细节

这个实现比较好理解,其实就是上述的土办法,一个循环搞定。

cpptemplate<class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value)
{
    while(first != last) {
        *first++ = value;
        ++value;
    }
}

C++ 0x的折衷

如果没有 C++11 的环境呢。我们可以借助 std::generate + 闭包结构体来模拟实现。

cpp#include <algorithm>

struct IncGenerator {
    int current_;
    IncGenerator (int start) : current_(start) {}
    int operator() () { return current_++; }
};

std::vector<int> ivec(10);
IncGenerator g(0);
std::generate(ivec.begin(), ivec.end(), g);
// ivec: 0,1,2,3,4,5,6,7,8,9

小二摸摸脑袋说,这还不如土办法写个循环呢。。。


pezy
3.1k 声望332 粉丝

一个 C++ 程序员