First of all, note that std::default_random_engine
and std::uniform_int_distribution<int>
are both non-portable in the same sense as rand()
is non-portable: they won't produce the same sequence of numbers on different platforms, because their behavior is implementation-defined. For uniform_int_distribution
there effectively is no portable alternative, so it's the best game in town. But for the PRNG itself, I don't think any expert would ever recommend default_random_engine
. Just pick a known engine, such as std::mt19937
. (Which isn't good but again it's the only game in town at the moment.)
For seeding: notice that you're giving only 32 bits of seed (and a very predictable seed at that) to the PRNG's constructor. You should be seeding from a random_device
, something like this (stolen from here):
std::random_device rd;
int data[624];
std::generate_n(data, std::size(data), std::ref(rd));
std::seed_seq sseq(data, std::end(data));
std::mt19937 g(sseq);
(Of course nobody does this in practice.)
for (int i = 1; i <= 100; i++)
Prefer
for (int i = 0; i < 100; ++i)
even if it means you have to refer to i+1
inside the loop. Using half-open ranges that start at 0 is good practice for everywhere in C and C++ and every modern language.
std::uniform_int_distribution<int> num(1, 100);
Personally I'd write this as
auto dist = std::uniform_int_distribution<int>(1, 100);
to get that nice clear =
separation visible at a glance. Also, notice my conventional variable names throughout: rd
for the random device, g
for the PRNG itself, dist
for the distribution. It might make sense to use a more descriptive name than dist
... but certainly num
is not more descriptive, and num
is less truthful — a distribution is not a single number!
Finally, you don't need that final return 0
(main
returns 0 on success by default), and you don't need std::endl
because '\n'
(or "\n"
) will do just as well.
But basically you're doing the dance correctly: PRNG created outside the loop, distribution called-like-a-function from inside the loop.
You could move the variable definition of the distribution outside the loop as well, if you wanted. It probably doesn't matter in practice because uniform_int_distribution
is unlikely to have any state worth preserving between iterations. But if it were a std::normal_distribution
, say, then destroying and recreating the distribution every time through the loop would be costing you basically 50% of your speed.
auto dist = std::uniform_int_distribution<int>(1, 100);
for (int i = 0; i < 100; ++i) {
std::cout << (i+1) << "==> " << dist(g) << '\n';
}