To be clear: the random number generators themselves are specified quite tightly--including the input parameters and results. To be technical, what's specified is the 10000th result from a default-constructed generator, but for any practical purpose a match on this result from a generator that's at least reasonably close to correct otherwise essentially guarantees that the generator is working correctly, and its outputs will match ever other similar generator for a given seed.
For example, a quick test:
#include <random>
#include <iostream>
int main() {
std::mt19937 r;
for (int i=0; i<10000-2; i++)
r();
for (int i=0; i<3; i++)
std::cout << r() << "\n";
}
...shows identical results with every (recent) compiler I have handy:
1211010839
4123659995
725333953
The second of those three is the value required by the standard.
More leeway is given, however, in the distribution templates. A uniform_int_distribution
has to map inputs to outputs uniformly, but there are different ways of doing that, and no requirement about which of those ways to use.
If you really need to produce a sequence of integers within a range that's not only uniformly distributed, but consistent between implementations, you'll probably have to implement your own distribution code. Doing this well isn't quite as trivial as most people initially think. You might want to look at one of my previous answers for a working implementation along with some explanation and a bit of test code.