3

I would like to generate uniformly distributed numbers on [0,1] in C++. I know that the following code would to the job

     std::random_device  rand_dev;
     std::mt19937  generator(rand_dev());
     std::uniform_real_distribution<double>  uni(0,1);
     std::cout << uni(generator);

But my issue is that I want to generate these numbers inside a class scope. And I don't want to initalize a new random number generator everytime I call a function of this class as I will need to call this function very often. Can I somehow use the same number generator for the entire class? I tried

class test{
      private: 
        std::random_device  rand_dev;
        std::mt19937  generator(rand_dev());
        std::uniform_real_distribution<double>  uni(0,1);

      public:
        void somefunction();
  };
test::somefunction(){std::cout << uni(generator);}

But this doesn't seem to work.

  • 1
    global to a class or global to an instance of a class? – selbie Apr 26 '20 at 07:13
  • @selbie it's enough if it's global to an instance of a class. I want to be able to call uni(generator) in every function of this instance of the class. –  Apr 26 '20 at 07:16
  • Am I not allowed to initalize the random number gnerator inside the private section of the class? Somehow the code is working in int main, but not iniside the class. –  Apr 26 '20 at 07:18
  • If you want to have a generator per instance of the class then you can initialise the private members in the constructor of test. – Ian Gralinski Apr 26 '20 at 07:22
  • 5
    Class member variables are initialized in constructors. BTW, you don't need to store `std::random_device` inside your class, if it will be used only once during initialization. Try to add a constructor like `test() : generator(std::random_device{}()), uni(0, 1) { }`. – Daniel Langr Apr 26 '20 at 07:25
  • The constructors of `generator` and `uni` are interpreted as function declarations, I think, because of most vexing parsing. You should put them in the constructors member initializer list (see Daniel Langr's comment). Maybe the [Singleton pattern](https://stackoverflow.com/questions/1008019/c-singleton-design-pattern) is a good approach for your problem, to provide a single instance of `test` across the whole application. – Lukas-T Apr 26 '20 at 07:28
  • @DanielLangr thank you. It took some reading as I'm quite a noob to programming, but thanks to your remark I got it to work. –  Apr 26 '20 at 08:16
  • 3
    Does this answer your question? [Use in a c++ class](https://stackoverflow.com/questions/34126262/use-random-in-a-c-class) – dasWesen Jul 16 '20 at 12:22
  • Also somewhat related: https://stackoverflow.com/questions/17691501/incorporating-boost-random-number-generator-as-a-class-variable – dasWesen Jul 16 '20 at 12:23

1 Answers1

1

Daniel Langr's comment:

Class member variables are initialized in constructors. By the way, you don't need to store std::random_device inside your class, if it will be used only once during initialization. Try to add a constructor like test() : generator(std::random_device{}()), uni(0, 1) { }

class test{
      private: 
        std::mt19937  generator; 
        std::uniform_real_distribution<double>  uni;
      public:
        test() : generator(std::random_device{}()), uni(0, 1) { }
  };
Peter O.
  • 32,158
  • 14
  • 82
  • 96