making a random generator global

Oct 15, 2017 at 11:59am
I have to generate a set of random numbers supported by different distributions.

I wish to use the ones provided by the STL, although I don't like the idea to set a different seed for all my generators, especially because I wish to hard code the seed for debug and, once all is set, use the std::random_device

Is it possible to make the generator visible to all the program objects? I have tried to declare it right before main, but it doesn't work. Alternatively I have tried to declare it an an header file, but this way the compiler doesn't like the fact that it is not constant and it is used in different files.

Any suggestions?
Last edited on Oct 15, 2017 at 12:00pm
Oct 15, 2017 at 2:38pm
Declare it in a header file.
 
extern std::mt19937 rng;

Define it in a source file.
 
std::mt19937 rng;
Oct 15, 2017 at 9:43pm
I don't think I got the point.

I declare it in an header file, than I declare and initialise it in main, before anything happens.

At this point, can my class access the generator? In my experience they can't (error in linking). So, should I add a private pointer to the generator to all the classes that want to access the rng?

Oct 16, 2017 at 3:02am
The actual rng object must exist only once, in one .cpp file. It doesn't actually matter where.

The header file only says that this thing exists somewhere. The most idiomatic way to do this is:

1
2
3
4
5
6
7
8
9
10
11
12
// my_rng.hpp
#ifndef MY_RNG_HPP
#define MY_RNG_HPP

#include <random>

namespace ericM
{
  extern std::mt19937 rng;
}

#endif 
1
2
3
4
5
6
7
8
9
// my_rng.cpp

#include <random>

namespace ericM
{
  std::mt19937 rng;
}
1
2
3
4
5
6
7
8
// main.cpp
#include <iostream>
#include "my_rng.hpp"

int main()
{
  std::cout << ericM::rng() << "\n";
}

Any cpp file that wishes to use the rng object must be told it exists; do so by #including "my_rng.hpp" (or whatever you wish to call it).

As long as my_rng.cpp is compiled and linked into the final application (because that is where rng actually exists), then anything can access it (because it is a global object in a globally-accessible namespace).


Another way to do it would be to use the singleton pattern.
Oct 16, 2017 at 6:54am
so, in my_rng.hpp the object is declared to exist "somewhere".
in my_rng.cpp the object is instantiated/defined (i.e. the compiler already knew its type, but is actually here that it finds the values).
Finally, any file that includes the header can access rng which point to the only one existing.
Is it right?

A last question: is the namespace required or is there only to prevent conflicts?

Oct 16, 2017 at 9:15pm
Yes and yes, and yes. :O)
Oct 17, 2017 at 10:51am
Thanks a million.
Topic archived. No new replies allowed.