// <algorithm> 
template <class ForwardIterator, class Generator>
    void generate (ForwardIterator first,
​        ForwardIterator last, Generator gen);

将一个函数的执行结果保存到指定范围的元素中,用于批量赋值范围中的元素。

该函数等价于:

template<class _FwdIt,
    class _Fn0> inline
    void _Generate(_FwdIt _First, _FwdIt _Last, _Fn0 _Func)
    {    // replace [_First, _Last) with _Func()
        for (; _First != _Last; ++_First)
            *_First = _Func();
    }
  • firstlast

    分别指向序列中初始及末尾位置的正向迭代器(Forward Iterators)。这个范围即 [first,last) ,包括 first 到 last 间的所有元素,包括 first 指向的元素,但不包括 last 指向的元素。

    gen

    生成器函数,该函数无参数,且返回值能够转换成迭代器所指向的值的类型。

    可以是函数指针(Function pointer)类型或函数对象(Function object)类型。

    返回

    无。

  • 例 1

    使用函数产生顺序数

    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <vector>
    
    namespace ClassFoo{
        int static n = 0;
        int NInc(){
            return ++n;
        }
        void Generate_1() {
            // 构造一个 vector 对象并填充
            std::vector<int> foo;
            foo.resize(15);
    
            // 使用函数
            // 将 foo 填充为 1~15 的顺序值 
            std::generate(foo.begin(), foo.end(), NInc);
    
            // 输出 foo 中的内容
            std::copy(
                foo.begin(),
                foo.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Generate_1();
        return 0;
    }

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 

    例 2

    使用函数产生随机数

    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <vector>
    #include <ctime>
    
    namespace ClassFoo{
        void Generate_2() {
            // 构造一个 vector 对象并填充
            std::vector<int> foo;
            foo.resize(15);
    
            // 用随机数填充 foo
            std::srand(unsigned(std::time(0)));
            std::generate(foo.begin(), foo.end(), std::rand);
    
            // 输出 foo 中的内容
            std::copy(
                foo.begin(),
                foo.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Generate_2();
        return 0;
    }

    9097 16967 12781 26629 15509 2195 31996 13894 10189 6199 24683 16937 6607 22632 22377 

    例 3

    使用可调用结构体对象

    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <vector>
    
    namespace ClassFoo{
        int static n = 15;
        struct _NDec{
            int operator()() { return n--; }
        }NDec;
        void Generate_3() {
            // 构造一个 vector 对象并填充
            std::vector<int> foo;
            foo.resize(15);
    
            // 使用结构体对象
            // 将 foo 填充为 15~1 的顺序值 
            std::generate(foo.begin(), foo.end(), NDec);
    
            // 输出 foo 中的内容
            std::copy(
                foo.begin(),
                foo.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Generate_3();
        return 0;
    }

    15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 

    例 4

    C++11

    使用 lambda 表达式

    #include <iostream>
    #include <algorithm>
    #include <iterator>
    #include <vector>
    #include <ctime>
    
    namespace ClassFoo{
        void Generate_4() {
            // 构造一个 vector 对象并填充
            std::vector<int> foo;
            foo.resize(15);
    
            // 用不大于 10 的随机数填充 foo
            std::srand(unsigned(std::time(0)));
            std::generate(foo.begin(), foo.end(), []() { return std::rand() % 10; });
    
            // 输出 foo 中的内容
            std::copy(
                foo.begin(),
                foo.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << std::endl;
        }
    }
    int main()
    {
        ClassFoo::Generate_4();
        return 0;
    }

    3 5 9 8 5 1 5 4 0 6 0 6 7 6 4 

  • 复杂度

    O(n)n 为 last first.

    数据争用相关

    修改在范围 [first,last) 中的所有元素,且每个元素确定只被访问一次。

    异常安全性相关

    如果生成器函数 gen、元素赋值操作或操作某个迭代器抛异常,该函数才会抛异常。

    注意 无效参数将导致未定义行为(Undefined behavior)