我想在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
答案 0 :(得分:7)
int foo(std::mt19937 rng)
您正在按值传递std :: mt19937生成器,因此当您将生成器传递给函数时,它不会从主函数中获取数字,因此将创建副本该生成器,只能在该函数内部进行修改,而不会影响main中的那个生成器。
您应该通过引用传递它,以便它修改main中的一个,并且在每次调用中,生成器都会创建不同的数字:
int foo(std::mt19937& rng)
答案 1 :(得分:3)
简短版本:更改foo
以用作参考。
int foo(std::mt19937& rng);
当函数参数是对象类型而不是引用时,该参数是与传递给它的参数对象不同的对象。在这里,由于参数类型和参数类型相同,因此您使用的是复制构造函数。
将类似mt19937
的熵源传递到类似uniform_int_distribution
的分布时,分布的operator()
称为熵源的operator()
。熵源的operator()
既返回伪随机值,又修改了熵源,以便其下一次调用将不同。
但是回到您的main
中,原始对象rng
尚未与发行版一起使用。它仅被复制,然后使用该副本。因此,下一次遍历循环时,将制作rng
的另一个副本。但是,由于这个新对象与未使用的rng
对象本质上相同,因此,一旦使用它只会再次产生相同的结果。
引用参数将解决所有问题,因为引用只是原始mt19937
对象的另一个名称,因此实际上每次对foo
的调用都在使用和更改原始对象。