Is there a reasonably simple way to replace srand() and rand()?
Full disclosure: I don’t like rand()
. It’s bad, and it’s very easily abused.
The C++11 random library fills in a void that has been lacking for a long, long time. The problem with high quality random libraries is that they’re oftentimes hard to use. The C++11 <random>
library represents a huge step forward in this regard. A few lines of code and I have a very nice generator that behaves very nicely and that easily generates random variates from many different distributions.
Given the above, my answer to you is a bit heretical. If rand()
is good enough for your needs, use it. As bad as rand()
is (and it is bad), removing it would represent a huge break with the C language. Just make sure that the badness of rand()
truly is good enough for your needs.
C++14 didn’t deprecate rand()
; it only deprecated functions in the C++ library that use rand()
. While C++17 might deprecate rand()
, it won’t delete it. That means you have several more years before rand()
disappears. The odds are high that you will have retired or switched to a different language by the time the C++ committee finally does delete rand()
from the C++ standard library.
I’m creating random inputs to benchmark different implementations of std::sort() using something along the lines of
std::vector<int> v(size); std::generate(v.begin(), v.end(), std::rand);
You don’t need a cryptographically secure PRNG for that. You don’t even need Mersenne Twister. In this particular case, rand()
probably is good enough for your needs.
Update
There is a nice simple replacement for rand()
and srand()
in the C++11 random library: std::minstd_rand
.
#include <random>
#include <iostream>
int main ()
{
std:: minstd_rand simple_rand;
// Use simple_rand.seed() instead of srand():
simple_rand.seed(42);
// Use simple_rand() instead of rand():
for (int ii = 0; ii < 10; ++ii)
{
std::cout << simple_rand() << '\n';
}
}
The function std::minstd_rand::operator()()
returns a std::uint_fast32_t
. However, the algorithm restricts the result to between 1 and 231-2, inclusive. This means the result will always convert safely to a std::int_fast32_t
(or to an int
if int
is at least 32 bits long).