C++11 中的随机数:有没有一种简单的方法可以将生成器种子放在代码的一个位置,然后在不同的函数中使用它?
Random numbers in C++11: is there a simple way to seed the generator in one place of the code, then use it in different functions?
在 C++11 之前,我使用了<cstdlib>
中的rand()
,选择在main()
函数中播种(或不播种(生成器非常简单(例如(,然后在 libraryA 中使用由 libraryB 中某处的函数生成的随机数。代码如下所示:
库B(生成随机数,老式方式(:
#include <cstdlib> // rand, RAND_MAX
double GetRandDoubleBetween0And1() {
return ((double)rand()) / ((double)RAND_MAX);
}
主程序:
#include <cstdlib> // srand
#include <ctime> // time, clock
int main() {
bool iWantToSeed = true; // or false,
// decide HERE, applies everywhere!
if(iWantToSeed){
srand((unsigned)time(0) + (unsigned int)clock());
}
// (...)
}
库A(使用来自库 B 的随机数,根据main()
中给出的种子生成(:
#include "../folderOfLibraryB/Utils_random.h" // GetRandDoubleBetween0And1
void UseSomeRandomness(){
for(int i = 0; i < 1000000; i++){
double nb = GetRandDoubleBetween0And1();
// (...)
}
}
很简单,对吧?
现在我想使用通过#include <random>
提供的 C++11 标准更新GetRandDoubleBetween0And1()
。我已经在这里和那里阅读并看到了示例,但我看不出如何使其适应我的三个模块。当然,将发动机播种在GetRandDoubleBetween0And1()
内并不是正确的做法......
您是否认为我必须在图书馆 A 中将种子引擎从main()
传递到UseSomeRandomness()
,然后在图书馆 B 中从UseSomeRandomness()
传递到GetRandDoubleBetween0And1()
?还是有更简单的方法?
你认为我必须将种子引擎从main((传递到LibraryA中的UseSomeRandomness((,然后从UseSomeRandomness((传递到LibraryB中的GetRandDoubleBetween0And1((吗?
是的。
实例化生成器一次,然后将指向它的引用或指针传递到想要使用它的任何上下文中。
这就像处理任何其他资源一样。
你可以做这样的事情:
#include <random>
inline double GetRandDoubleBetween0And1() {
thread_local static std::mt19937 gen{std::random_device{}()};
thread_local static std::uniform_real_distribution pick{0.0, 1.0};
return pick(gen);
}
inline
意味着您可以将其放在头文件中,编译器将仅创建静态对象的一个副本,它将在链接时解析该副本。但是,如果您在动态库中使用它,您将获得不同的副本。在这种情况下,您可以将此函数放在其自己的库中,并将其链接到使用该函数的每个程序。
thread_local
确保线程安全(每个线程一个随机生成器(,并且是静态的,它们只初始化一次。
我的"随机"库提供了一个围绕 C++11 个随机类的高度方便的包装器。你可以用一个简单的"get"方法做几乎所有的事情。
对于您的用例,您可以将自动种子random_static包装器与静态 API 一起使用。
例子:
#include "effolkronium/random.hpp"
using Random = effolkronium::random_static;
auto Func( ) {
return Random::get(-10, 10 )
}
auto Func2( ) {
return Random::get(-10, 10 )
}
int main( ) {
// Seed static internal engine
Random::seed( MySuperSeed );
}
它是仅单个标头库。
查看github页面: https://github.com/effolkronium/random
- 我的目标是编写一个程序来计算和存储字符串在字符数组中出现的位置
- 将一个向量插入另一个向量的某个位置
- 将所有 URL 组织在类中的一个位置
- 计算在同一位置至少包含一个常用字符的不同字符串对
- 如何在另一个字符串的x位置插入一个字符串?
- C++强制变量到一个固定的内存位置
- 创建一个类来访问和指定向量类型,并构建一个获取位置并为其分配区域的类
- 在多维向量中的特定位置添加一个值
- C++将包含的库 (ref DLL) 从根目录更改为另一个位置
- 查找 2D 向量的位置,该向量是类C++的一个元素
- 创建一个函数以在给定位置将元素插入到列表中
- C++11 中的随机数:有没有一种简单的方法可以将生成器种子放在代码的一个位置,然后在不同的函数中使用它?
- 快速从文件中读取下一个字符串,而无需移动文件的位置
- 给定一个用三角形镶嵌的补丁,如何修改其新的顶点位置
- 如何正确删除一行控件并在该位置动态创建一个新控件
- 如何在点击的QPushButton的位置画一个形状
- 如何编写一个 void 函数,该函数将在数组中搜索值,并通过引用将该值的位置传递回 main 函数
- 将过滤器中的所有.cpp和.h移动到另一个项目并更正其文件夹位置
- 如何在 MFC 中围绕当前光标的位置绘制一个矩形
- 访问违反读数位置时,当另一个垫子中的push_back垫子