我想在main函数之外生成随机数,但即使使用库并播种随机数生成器,输出也不是随机的。任何帮助表示赞赏。
#include <iostream>
#include <random>
#include <time.h>
int foo(std::mt19937 rng)
{
std::uniform_int_distribution<int> distr(0, 9);
return distr(rng);
}
int main()
{
std::random_device rd;
std::mt19937 rng(rd());
for (int j=0; j<10; j++)
{
std::cout << foo(rng) << " ";
}
return 0;
}
随着输出
5 5 5 5 5 5 5 5 5 5
int foo(std::mt19937 rng)
您是按值传递std :: mt19937生成器,因此当您将生成器传递给函数时,它不会从main中获取数字,因此创建该生成器的副本,该副本仅在该函数内部进行修改,并不影响主要的那个。
您应该通过引用传递它,因此它会修改main中的那个,并且在每次调用中,生成器将创建不同的数字:
int foo(std::mt19937& rng)
简短版本:更改foo
以获取参考。
int foo(std::mt19937& rng);
当函数参数是对象类型而不是引用时,该参数是与传递给它的参数对象不同的对象。这里由于参数类型和参数类型相同,因此您使用的是复制构造函数。
当像mt19937
这样的熵源传递给像uniform_int_distribution
这样的分布时,分布的operator()
称为熵源的operator()
。熵源的operator()
都返回伪随机值并且还修改熵源以使其下一次调用不同。
但回到你的main
,原始对象rng
没有用于分发。它只被复制,然后使用该副本。因此,下次循环时,会制作另一份rng
副本。但由于这个新鲜对象与未使用的rng
对象基本相同,因此使用它只会再次产生相同的结果。
引用参数将修复所有这些,因为那时引用只是原始mt19937
对象的另一个名称,因此每次调用foo
实际上都在使用和更改原始对象。