使用 std::uniform_int_distribution 并稍后定义其范围

esw*_*aat 4 c++ random c++11

我有一个问题,我想std::uniform_int_distribution在一个结构中创建一个,然后再给出它的范围。下面是我想要的。

#include <random>
#include <iostream>

std::random_device rd;
std::mt19937 gen(rd());

struct group_s {
   int k;
   std::uniform_int_distribution<> dis;
} group;


int main()
{  
    group.dis(0,19);
    std::cout << group.dis(gen) << ' ';
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

no match for call to '(std::uniform_int_distribution<>) (int, int)'
  cpu_group.dis(0,19);
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?

T.C*_*.C. 5

使用param()

using param_t = std::uniform_int_distribution<>::param_type;

group.dis.param(param_t(0, 19));
Run Code Online (Sandbox Code Playgroud)

如果每次使用分布时参数都发生变化,那么您也可以考虑使用二参数重载来operator()代替:

std::cout << group.dis(gen, param_t(0, 19)) << ' ';
Run Code Online (Sandbox Code Playgroud)

由于允许分布对象存储在先前operator()调用期间获得的额外熵位,因此这种方法比构建新的分布对象并分配它更有效。

请注意,cppreference 页面不完整,并且没有记录标准对param_type. 给定一个分布类型D及其关联的param_type P

对于D分布的参数对应的每个取参P构造函数,都应有一个对应的构造函数符合相同的要求,取参数的数量、类型和默认值都相同。而且,对于D那个返回值对应分布的参数的每个成员函数,都P应该有一个对应的具有相同名称、类型和语义的成员函数。

(第 26.5.1.6 节 [rand.req.dist]/p9)


Amx*_*mxx 4

你可以这样做

group.dis = std::uniform_int_distribution<>(0,19);
Run Code Online (Sandbox Code Playgroud)

或者

group.dis.param(std::uniform_int_distribution<>::param_type(0,19));
Run Code Online (Sandbox Code Playgroud)

另一种方法是将方法添加到您的结构中

struct group_s {
    int k;
    std::uniform_int_distribution<> dis;
    void set(int a, int b) { dis = std::uniform_int_distribution<>(a,b); }
} group;


group.set(0,19);
Run Code Online (Sandbox Code Playgroud)