0

There are several good answers like this that offer a concise random-only application, but I'm having trouble expanding from that to a small part of a larger application.

Here's what I'm doing:

#include <random>

class RandomFP16
{
public:
    static RandomFP16* GetInstance();
    int GetRandom();
private:
    static RandomFP16* singleton;
    RandomFP16();
    std::mt19937 mt;
    std::uniform_int_distribution<int> dist;
};

RandomFP16* RandomFP16::GetInstance()
{
    if(singleton == 0)
    {
        singleton = new RandomFP16();
    }
    return singleton;
}

RandomFP16::RandomFP16()
{
    std::random_device rd;
    //next two lines have errors
    mt(rd());
    dist(0x00000000, 0x00010000);   //fixed-point 16.16
}

int RandomFP16::GetRandom()
{
    return dist(mt);
}

So basically, I want one shared random generator that can be used anywhere anytime...at random. :-) Coming from embedded C and Windows C#, I see some strange syntax being used here, so I'm not sure how to structure things to get rid of these errors:

error: no match for call to '(std::mt19937 {aka std::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>}) (std::random_device::result_type)'
     mt(rd());
            ^

.

error: no match for call to '(std::uniform_int_distribution<int>) (int, int)'
 dist(0x00000000, 0x00010000);
                            ^
Community
  • 1
  • 1
AaronD
  • 503
  • 1
  • 7
  • 23

1 Answers1

0

Okay, I got it. Posting anyway to save someone some work.


#include <random>

class RandomFP16
{
public:
    static RandomFP16* GetInstance();
    int GetRandom();
private:
    static RandomFP16* singleton;
    RandomFP16(std::random_device::result_type seed);
    std::mt19937 mt;
    std::uniform_int_distribution<int> dist;
};

RandomFP16* RandomFP16::singleton = 0;

RandomFP16* RandomFP16::GetInstance()
{
    if(singleton == 0)
    {
        std::random_device rd;
        singleton = new RandomFP16(rd());
    }
    return singleton;
}

RandomFP16::RandomFP16(std::random_device::result_type seed)
    : mt(seed), dist(0x00000000, 0x00010000)    //fixed-point 16.16
{
}

int RandomFP16::GetRandom()
{
    return dist(mt);
}

Turns out the class definition was right; the problems were all in the implentation:

  • The static variable needs to be declared again outside the class definition. (no idea why)
  • Local variables (not pointers) with constructors must be initialized like this.
    • That added an argument to this constructor, which then had to be fed from GetInstance()
AaronD
  • 503
  • 1
  • 7
  • 23