Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Initializing std::random_uniform_real_distribution with paranthesis

In the documentation of std::uniform_real_distribution, the notation for initializing the uniform real random number generator is to use round brackets:

std::uniform_real_distribution rand01(0,1)

However, when I define this as a member of a class variable:

#include <iostream>
#include <random>

class randomnumber
{
   public: 
      randomnumber()
      {
         std::random_device rd;
         generator.seed(rd()); 
      };

      double get_rn()
      {
         return rand01(generator);
      }

   private :
      std::mt19937 generator; 
      std::uniform_real_distribution<double> rand01(0.,1.);
};

int main(int argc,char *argv[])
{
   randomnumber randnum;
   for(int i=0;i<100;i++)
      std::cout << randnum.get_rn() << std::endl;
}

The compiler fails with an error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

randtest.cpp:20:53: error: expected identifier before numeric constant
   20 |       std::uniform_real_distribution<double> rand01(0.,1.);
      |                                                     ^~
randtest.cpp:20:53: error: expected ‘,’ or ‘...’ before numeric constant
randtest.cpp: In member function ‘double randomnumber::get_rn()’:
randtest.cpp:15:24: error: cannot convert ‘std::mt19937’ {aka ‘std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>’} to ‘int’
   15 |          return rand01(generator);
      |                        ^~~~~~~~~
      |                        |
      |                        std::mt19937 {aka std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>}
randtest.cpp:20:53: note:   initializing argument 1 of ‘std::uniform_real_distribution<double> randomnumber::rand01(int)’
   20 |       std::uniform_real_distribution<double> rand01(0.,1.);

The fix is to use curly brackets {} instead of the round brackets ().

The question is, is this fix a fundamental fix? Meaning, can I trust the fixed code with {} to always generate uniform random number between 0 and 1?
Also for the future purposes for similar cases, it would be greaet if someone can explain me why compiler behaves in this way.

I use for compiling g++ g++ -std=c++11 randtest.cpp:

g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

>Solution :

is this fix a fundamental fix?

For this code, yes. But not in general.

can I trust the fixed code with {} to always generate uniform random number between 0 and 1?

Yes, std::uniform_real_distribution<double> rand01{0.,1.}; defines a uniform distribution with parameters of 0 and 1, by calling the exact same constructor that std::uniform_real_distribution rand01(0,1) does for non-class scopes.

But the way that the compiler searches for constructors is different when braces are used. Particularly for classes intended to work as collections (e.g. std::vector), braces may choose a different constructor. A strong sign of this happening is when the class has a constructor (or multiple) for some std::initializer_list<...>.

std::uniform_real_distribution::uniform_real_distribution() doesn’t have special handling for initializer lists which is what makes your specific example safe.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading