I have problem where I want to create a std::uniform_int_distribution
in a struct and then give its range later. Below is what I want.
#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) << ' ';
}
I am getting the following error:
no match for call to '(std::uniform_int_distribution<>) (int, int)'
cpu_group.dis(0,19);
How do I do this?
Use param()
:
using param_t = std::uniform_int_distribution<>::param_type;
group.dis.param(param_t(0, 19));
If the parameters change every time you use the distribution, then you can also consider using the two-parameter overload of operator()
instead:
std::cout << group.dis(gen, param_t(0, 19)) << ' ';
As distribution objects are allowed to store extra bits of entropy obtained during a previous operator()
call, this approach can be more efficient than constructing a new distribution object and assigning it.
Note that the cppreference page is incomplete and doesn't document the requirements the standard imposes on param_type
. Given a distribution type D
and its associated 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 ofD
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)
You can just do
group.dis = std::uniform_int_distribution<>(0,19);
or
group.dis.param(std::uniform_int_distribution<>::param_type(0,19));
Another way would be to add a method to your struct
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With