随机数在测试、游戏、仿真和安全等很多问题中都非常有用。为了适应各种各样的应用需求,标准库在<random>中提供了很多种不同的随机数生成器。随机数生成器包括两部分:
    【1】一个引擎( engine),负责生成一组随机值或者伪随机值。
    【2】一种分布( distribution),负责把引擎产生的值映射到某个数学分布上。
    常用的分布包括 uniform_int_distribution(生成的所有整数概率相等)、 normal_distribution
    (正态分布,又名“铃铛曲线”)和 exponential_distribution(指数增长),它们的范围各不相同。例如:

    1. using my_engine default_random_engine; //引擎类型
    2. using my_distribution= uniform_int_distribution<>; //分布类型
    3. my_engine re{}; //默认引擎
    4. my_distribution one_to_six {1,6}; //该分布把随机数映射到1~6的范围
    5. auto die=bind(one_to_six,re); //得到一个随机数生成器
    6. int x= die(); //掷骰子:x得到的值位于1~6之间

    标准库函数bind()生成一个函数对象,它会把第2个参数(re)作为实参绑定到第一个参数( one_to_six函数对象)的调用中(见33.5.1节)。因此,调用die()等价于调用one_to_six(``re``).
    在设计和实现标准库随机数组件时,我们非常注重它的泛化能力和性能,因此曾经有位专家把它评价为“实现随机数库的榜样和标杆”。不过它对于入门级的程序员来说稍显繁杂且不够友好。在上面的代码中,我们用 using语句稍微解释了一下生成随机数的过程,当然也可以写成下面的形式

    1. auto die= bind(uniform_int_distribution<>(1,6), default_random_engine{})

    至于说哪个版本更易读完全取决于代码上下文和读者自己的感觉。
    对于初学者来说,完整版本的随机数生成器显得有些过于正式且不易使用,有一个简易版本可作为替代。例如:

    1. Rand_int rnd{1,10}; //构建一个随机数生成器,生成1~10之间的随机数
    2. int x=rnd(); //x是1~10之间的随机数

    (推荐使用)我们该如何得到这个新版本的随机数生成器呢?显然必须在 Rand int类的内部实现与die()类似的功能才行:

    1. class Rand_int
    2. {
    3. public:
    4. Rand_int(int low, int high):dist(low, high){}
    5. int operator()(return dist{re};)
    6. private:
    7. default_random_engine re;
    8. uniform_int_distribution<> dist;
    9. };

    Rand_int()的定义仍然是“专家级的”,不过使用起来已经变得很容易了,甚至初学者在C++课程的第一周就能学会使用它。例如:

    1. int main()
    2. {
    3. Rand_int rnd{0,4}; //创建一个随机数生成器
    4. vector<int> histogram(5); //构建一个相应尺寸的vector
    5. for(int i=0;i!=200;++i)
    6. {
    7. ++histogram[rnd()]; //用[0:4]之间的每个数字出现的次数填充histogram
    8. }
    9. for(int i=0;i!=mn.size();++i)
    10. {
    11. cout<<i<<'\t';
    12. for(int j=0;j!=mn[i];++j)
    13. cout<<'*';
    14. cout<<endl;
    15. }
    16. }

    输出结果是如下所示的一个均匀分布(统计差异在合理范围之内):

    1. 0 ****************************************
    2. 1 ************************************
    3. 2 *********************************************
    4. 3 *************************************
    5. 4 ******************************************

    因为C++没有标准图形库,所以我们使用了“ASCI图形”。众所周知,有很多为C++设计的开源或者商业的GUI库,但是在本书中我们尽量只使用ISO标准之内的功能。
    关于随机数的更多内容请参阅40.7节。