Engines are responsible for generating uniformly distributed random numbers. One such provided engine is the Mersenne Twister engine. Distributions use the output of engines to mold the numbers to a specific distribution.

Consider the following example.

mt19937 engine(static_cast<unsigned long>(time(NULL)));

exponential_distribution<double> dist;

cout << dist(engine) << endl;

The output is a single random number, following the exponential distribution. Now let's say we want to use this in a call to

`generate_n`

with a lambda:

mt19937 engine(static_cast<unsigned long>(time(NULL)));

exponential_distribution<double> dist;

generate_n(ostream_iterator<double>(cout, "\n"), 20, [&dist,&engine]() -> double { return dist(engine); });

You're probably thinking that a simple

`for`

loop would be much cleaner here, and I don't disagree. However, there is one other thing we can do:

mt19937 engine(static_cast<unsigned long>(time(NULL)));

exponential_distribution<double> dist;

variate_generator<mt19937, exponential_distribution<double>> gen(engine, dist);

generate_n(ostream_iterator<double>(cout, "\n"), 20, gen);

That's right --

`variate_generator`

is provided to us so that we can encapsulate an engine along with a distribution. That way, a simple `gen()`

gets us a random number using the desired engine and distribution.