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

Use std::uniform_int_distribution and define its range later

我想在结构中创建一个 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) << ' ';
}

我收到以下错误:

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

我该怎么做?

你可以做到

group.dis = std::uniform_int_distribution<>(0,19);

group.dis.param(std::uniform_int_distribution<>::param_type(0,19));

另一种方法是向您的结构添加一个方法

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);

你应该做

group.dis = std::uniform_int_distribution<>(0,19);

而不是

group.dis(0,19);

此外,您的代码似乎是在没有直接引用 here 的情况下获取的,因此 link 作为一种附注引用应该是有序的。

使用param():

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

group.dis.param(param_t(0, 19));

如果每次使用分布时参数都变了,那你也可以考虑用operator()的双参数重载代替:

std::cout << group.dis(gen, param_t(0, 19)) << ' ';

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

请注意,cppreference 页面不完整,未记录标准对 param_type 施加的要求。给定分布类型 D 及其关联的 param_type P,

For each of the constructors of D taking arguments corresponding to parameters of the distribution, P shall have a corresponding constructor subject to the same requirements and taking arguments identical in number, type, and default values. Moreover, for each of the member functions of D that return values corresponding to parameters of the distribution, P shall have a corresponding member function with the identical name, type, and semantics.

(§26.5.1.6 [rand.req.dist]/p9)