C 11中的怪异RNG行为在定义并在不同的位置进行调用

Weird RNG behavior in C++11 when defined and called in different places

本文关键字:位置 调用 定义 RNG      更新时间:2023-10-16

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

在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 之间有什么区别main()?

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

任何人都可以说明rnd1rnd2rnd3之间的区别并让rnd2工作吗?谢谢!

无法保证跨翻译单元的初始化顺序。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文件中,并使其可用,而不是外部变量。

甚至更好,如果您的意图是使其成为单身人士,那就这样做。将它们放入单例类,然后使用MySingletonGenerator::instance().nextValue()