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

How to initialize static random generator in c++?

I have Random class, and I don`t know how correctly make initialization of random generator.

// random.h
#pragma once

#include <random>

class Random
{

private:
    static std::uniform_real_distribution<float> sDistribution_;
    static std::mt19937 sGenerator_;
};
// random.cpp
#include "random.h"

std::mt19937 Random::sGenerator_(std::random_device());
std::uniform_real_distribution<float> Random::sDistribution_(0.0f, 1.0f);

When I make this, I have an error: declaration is not compatible with std::mt19937.

So, how correctly initialize this thing?

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

>Solution :

std::mt19937 Random::sGenerator_(std::random_device());

is an instance of the most vexing parse.
You wanted to perform direct initialization, but you’re actually:

declaring Random::sGenerator_ as a function taking a pointer to a function taking no parameters, and returning std::random_device. The Random::sGenerator_ function returns std::mt19937.

This is what the compiler thinks, and it conflicts with the original definition of Random::sGenerator_, which declares it as a static data member of type std::mt19937.

The solution is very simple: std::random_device is a type, not a function, so you need to initialize it before calling it, like:

std::mt19937 Random::sGenerator_{std::random_device{}()};
// or
std::mt19937 Random::sGenerator_{std::random_device()()};
// or
std::mt19937 Random::sGenerator_(std::random_device{}());

In general, preferring list initialization is considered good practice by some, because it avoids this parsing ambiguity. Just be aware that it works differently when a type has a constructor taking std::initializer_list (not a problem for any of the types we’re using).

Since C++17

You can also initialize the static data member in the class, like:

class Random
{
private:
    static inline std::uniform_real_distribution<float> sDistribution_{0, 1};
    static inline std::mt19937 sGenerator_{std::random_device{}()};
};

Note: if all your class does is storing static data members, it should likely just be a namespace, not a class.

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