Mersenne Twister random-number generator function
Math

Well, I believe usually you could avoid the math, but this is a special case. The main things to cover is random variable, random functions and distributions. It is gonna help a lot. Do note that int distribution is discrete, whereas real distribution is continuous.

Code Review


Incorrect usage of twister

First of all, std::mt19937 generates only 32 bit random numbers. This means that by truncating it to int (not always, depends on the platform), the code will discard higher (or lower) 16 bits of the number.

The twister has state, which means that when function generates one random number, it will discard the state and start from scratch when called again. Although std::random_device might normalize the behavior, the output will not be as intended.
Incorrect usage of distribution

std::uniform_distribution has a constructor taking T min, T max, which means that unsigned long long will overflow the arguments, which I believe is undefined behavior.

Return type is unsigned long long, but generates values are of type int, which means that higher (or lower) bits will be zero or garbage. Both of the cases are wrong. 


Different solution

If you want a generator without all of the hoops to jump through, just slam everything into a class. Here is the rough sketch (might not compile):

#include &lt;random&gt;

class uniform_int_generator
{
    std::mt19937_64 twister;
public:
    uniform_int_generator():
                  twister(std::random_device{}())
    {}

    unsigned long long operator()(unsigned long long max_val, unsigned long long min_val)
    {
        std::uniform_int_distribution&lt;unsigned long long&gt; distr(max_val, min_val);
        return distr(twister);       
    }
};


You might want to add some customization points using templates. Anyway, if you need more, make this one compile and post question with the updated code.