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

5

我有一个问题,想要在结构体中创建一个 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);

我该怎么做?


不太可能。错误与您的代码不匹配。此外,“gen”的定义是否受MVP的影响? - Lightness Races in Orbit
1
只有当rd是一个类型名称时才成立。 - Casey
3个回答

6
使用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,
对于D的每个构造函数,该构造函数接受与分布参数相对应的参数,P必须具有相应的构造函数,该构造函数受到相同要求并采用数量,类型和默认值完全相同的参数。此外,对于返回与分布参数相对应的值的D的每个成员函数,P必须具有相应的成员函数,名称,类型和语义相同。
(§26.5.1.6 [rand.req.dist] / p9)

我很好奇,为什么 group.dis.param({0, 19}); 看起来不起作用。是个bug吗?std::uniform_int_distribution<>{0,2} 看起来是有效的。 - Yakk - Adam Nevraumont
@Yakk 可能构造函数是 explicit 的,就像 std::uniform_int_distribution 的构造函数接受两个整数一样。 - T.C.

4
你可以直接执行。
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);

或者使用非静态数据成员初始化器 std::uniform_int_distribution<> dis = std::uniform_int_distribution<>{0, 19}; - Praetorian
@Praetorian 在C++11之前使用std::uniform_int_distribution有点困难 :) - T.C.
@T.C. 呵呵。有 tr1/random 但是如果我没记错的话,它的名字稍微有点不同。 - Praetorian
uniform_int_distribution 有移动构造函数是有保证的吗? - Yakk - Adam Nevraumont
但这意味着这个答案是不正确的,对吗? @eswaat - Yakk - Adam Nevraumont
显示剩余3条评论

0

你应该做

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

而不是

group.dis(0,19);

此外,您的代码似乎是直接从这里复制而来的,因此一个链接作为致敬引用会更合适。

快速查看cppreference并没有显示为std::uniform_int_distribution<>保证移动构造函数。你有相反的证据吗? - Yakk - Adam Nevraumont

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接