3

I am currently making a class for which I'd like one of the private members to be initialised with a random number each time the object is created. The following code causes no problem:

private: unsigned random = rand() % 10; 

I would, however, like to use the C++11 random engines and distributions to do this. I would like to be able to do something along the lines of the following code, which will not compile but will give a general idea of what I'm trying to do:

private: unsigned random = distribution(mersenne_generator(seed)); static std::random_device seed_generator; static unsigned seed = seed_generator(); //So that it's not a new seed each time. static std::mt19937 mersenne_generator; static std::uniform_int_distribution<unsigned> distribution(0, 10); 

This code won't compile because I'm trying to define some of the static members in the class. I'm not sure where to define them, however. I could create a member function that initialises everything, but then I would have to run it in main, which I don't want to. I would like to just sort out all the random definitions in class so that when I create an object in main, it will create the random number implicitly. Any suggestions?

3
  • This might help stackoverflow.com/questions/11498304/… Commented Mar 18, 2014 at 19:43
  • Is this question just how to define/initialize static data members? Could you post a SSCCE? Commented Mar 18, 2014 at 19:52
  • I'm trying to implement the same functionality as the first block of code (which generates a random number for that member each time an object is created) using C++11 random generators and engines. I have no idea how to do so, the static data members are just my attempt, but it doesn't compile. I included it as a sort of pseudocode to show my intention. Commented Mar 18, 2014 at 19:56

1 Answer 1

8

You need to define the static data members outside the class definition. For instance, this will work:

struct foo { private: unsigned random = distribution(mersenne_generator); static std::random_device seed_generator; static unsigned seed; static std::mt19937 mersenne_generator; static std::uniform_int_distribution<unsigned> distribution; }; std::random_device foo::seed_generator; unsigned foo::seed = seed_generator(); std::uniform_int_distribution<unsigned> foo::distribution(0, 10); std::mt19937 foo::mersenne_generator(foo::seed); 

The definitions for the static data members should be placed in a .cpp file, else you run the risk of violating the one definition rule.

Live example

Sign up to request clarification or add additional context in comments.

3 Comments

TIL: name lookup in brace-or-equal-initializers for NSDM is the same as name lookup inside member function definitions (it's postponed until the end of the class definition).
I would encapsulate the static data members into a static member function so as to avoid the requirement for separate out-of-class definitions, like so. Make the linker do the work ;)
Awesome, that did work. Thanks a lot, static members always confuse me with definitions vs declarations. Edit: Thanks Casey, that is some sexy code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.