1

I am probably doing more effort than necessary but who cares, let's try to solve this problem: I would like to use the "random_device" generator from <random> in my code. But that might not be available on some systems (according to specs), so I would like to have mt19937 as a backup (but whatever generator I use, I would like to have the same variable name at the end). Now, I can try the random_device to see if it is working, but what then? If I use an if statement, my generator will vanish after the if. If I declare it, I cannot change the type afterwards. Below the code, that does not work.

bool random_working=true;
try
{
    random_device rd; //throws exception when not able to construct
}
catch(exception& e)
{
    cout<<"Exception: ''random_device'' not working, switching back to mt19937"<<endl;
    random_working=false;
}
if(random_working)
    random_device mc; //for _M_onte-_C_arlo
else
        mt19937 mc;
István
  • 11
  • 4
  • 1
    You should not use `std::random_device` alone to generate numbers, see e.g., https://stackoverflow.com/questions/39288595/why-not-just-use-random-device. – Holt Jul 07 '19 at 12:47
  • Thank you, I know that, the distributions are created later on, I didn't want to paste too much code (the distribution part works well). – István Jul 07 '19 at 12:58
  • 3
    `std::random_device` should be used to seed `mt19937`. The generation rate of `std::random_device` is allow to be very slow as true randomness takes time without custom hardware support. – Richard Critten Jul 07 '19 at 13:00
  • @István I mean that you should not feed a `std::random_device` to a distribution but only use it to seed your `mt19937` or whatever engine you are using. – Holt Jul 07 '19 at 13:00
  • Write a function that returns a working generator. –  Jul 07 '19 at 13:01
  • Background: A talk by STL on random generation: https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful – Richard Critten Jul 07 '19 at 13:04
  • 1
    @Richard It's also allowed to always return the same value, making it useless. –  Jul 07 '19 at 13:07

1 Answers1

0

This documentation says that std::random_device may be a deterministic source on some platforms, thus leading to always the same sequence.

You can always keep std::mt19937 and seed() it with something time dependant like in the good old days of std::rand() and std::srand().

And then you will have to use a random distribution that will consume this random generator and provide you with the random values you expect.

For example

#include <iostream>
#include <random>
#include <chrono>

int
main()
{
  //-- create and seed a general purpose random generator --
  using gen_t = std::mt19937;
  const auto now{std::chrono::system_clock::now().time_since_epoch()};
  const auto seed=gen_t::result_type(
    std::chrono::duration_cast<std::chrono::microseconds>(now).count());
  gen_t rndGen{seed};

  //-- create a uniform distribution of integer values in [0;255] --
  std::uniform_int_distribution<int> uniDist{0, 255};

  //-- draw a random integer value --
  const int guessThatInteger=uniDist(rndGen);

  std::cout << guessThatInteger << '\n';
  return 0;
}
prog-fh
  • 13,492
  • 1
  • 15
  • 30