在不同的地方定义和调用时,C ++ 11中的奇怪RNG行为

时间:2017-12-04 03:56:39

标签: c++ c++11 random

我正在尝试编写一个多文件程序,其中包括以下与随机数生成相关的代码:

help.h文件中的

extern random_device rand_dev;
extern ranlux48 rand_eng;
extern uniform_real_distribution<> zero2one_dist;
help.cpp文件中的

#include "help.h"
random_device rand_dev;
ranlux48 rand_eng{ rand_dev() };
uniform_real_distribution<> zero2one_dist(0, 1);
main.cpp文件中的

#include "help.h"
//identical as help.cpp, just for illustration of the problem
random_device rand_dev1;
ranlux48 rand_eng1{ rand_dev1() };
uniform_real_distribution<> zero2one_dist1(0, 1);
//random number generation
float rnd1 = zero2one_dist1(rand_eng1);
float rnd2 = zero2one_dist(rand_eng);
//main function
int main()
{
    //another random number generation.
    float rnd3 = zero2one_dist(rand_eng);
    //output
    cout << rnd1 << endl << rnd2 << endl << rnd3 << endl;
    return 0;
}

所需的结果是在0和1之间输出三个随机数,但rnd1rnd3生成正确的结果,但rnd2保持0?!

我在这里完全感到困惑,外部文件 help.h main.cpp 中定义的区别是什么&#39 ; s main()内部和外部的调用之间的区别?

在我的实际工作中,我需要以rnd2的形式编写代码,但现在它不会工作,我也不知道为什么。

任何人都可以说明rnd1rnd2rnd3之间的差异并让rnd2发挥作用吗?谢谢!

1 个答案:

答案 0 :(得分:3)

无法保证翻译单元的初始化顺序。可以在rnd2之前或之后初始化zero2one_dist。如果您确实需要外部分发对象或辅助函数,请使用表单rnd3,例如:

float rand_zero2one()
{
   static random_device rand_dev;
   static ranlux48 rand_eng{ rand_dev() };
   static uniform_real_distribution<> zero2one_dist(0, 1);
   return zero2one_dist(rand_eng);
}

这可以保证在首次调用函数之前初始化静态变量。将它放在help文件中,使其可用而不是外部变量。

或者甚至更好,如果你打算让它成为一个单身人士,那就去做吧。将它们放入singleton class,然后使用MySingletonGenerator::instance().nextValue()