Skip to main content
added 834 characters in body
Source Link
Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145

If you were going to get a number from random_device at every call, you might as well just use it directly:

int random_in_range(int min, int max) {
    std::random_device rd;
    std::uniform_int_distribution<int> uni(min, max);
    return uni(rd());
}

std::random_device is intended to be a front-end for a truly random bit source. The major shortcoming is that in many cases it has fairly limited bandwidth, so you'd prefer to avoid calling it every time you need a number.

If you do want to use mt19937 (a perfectly fine idea in many cases) I'd personally use a function-object instead of a function:

class random_in_range { 
    std::mt19937 rng;
public:
    random_in_range() : rng(std::random_device()()) {}
    int operator()(int low, int high) { 
        std::uniform_int_distribution<int> uni(low, high);
        return uni(rng);
    }
};

This does have some shortcoming though: people may use a temporary of this type in a loop:

for (int i=0; i<10; i++)
    std::cout << random_in_range()(0, 1);

...which puts you back where you started. You need to do something like:

random_in_range r;
for (int i=0; i<10; i++)
    std::cout << r(0, 1);

...to get the results you want (i.e., seed once, call multiple times).

If you were going to get a number from random_device at every call, you might as well just use it directly:

int random_in_range(int min, int max) {
    std::random_device rd;
    std::uniform_int_distribution<int> uni(min, max);
    return uni(rd());
}

std::random_device is intended to be a front-end for a truly random bit source. The major shortcoming is that in many cases it has fairly limited bandwidth, so you'd prefer to avoid calling it every time you need a number.

If you were going to get a number from random_device at every call, you might as well just use it directly:

int random_in_range(int min, int max) {
    std::random_device rd;
    std::uniform_int_distribution<int> uni(min, max);
    return uni(rd());
}

std::random_device is intended to be a front-end for a truly random bit source. The major shortcoming is that in many cases it has fairly limited bandwidth, so you'd prefer to avoid calling it every time you need a number.

If you do want to use mt19937 (a perfectly fine idea in many cases) I'd personally use a function-object instead of a function:

class random_in_range { 
    std::mt19937 rng;
public:
    random_in_range() : rng(std::random_device()()) {}
    int operator()(int low, int high) { 
        std::uniform_int_distribution<int> uni(low, high);
        return uni(rng);
    }
};

This does have some shortcoming though: people may use a temporary of this type in a loop:

for (int i=0; i<10; i++)
    std::cout << random_in_range()(0, 1);

...which puts you back where you started. You need to do something like:

random_in_range r;
for (int i=0; i<10; i++)
    std::cout << r(0, 1);

...to get the results you want (i.e., seed once, call multiple times).

Source Link
Jerry Coffin
  • 34.1k
  • 4
  • 77
  • 145

If you were going to get a number from random_device at every call, you might as well just use it directly:

int random_in_range(int min, int max) {
    std::random_device rd;
    std::uniform_int_distribution<int> uni(min, max);
    return uni(rd());
}

std::random_device is intended to be a front-end for a truly random bit source. The major shortcoming is that in many cases it has fairly limited bandwidth, so you'd prefer to avoid calling it every time you need a number.