On 4 Aug 2009, at 06:39, Diederick C. Niehorster wrote:


I have the following requirements:

1) only one generator may exist (hence the singleton), it does not
matter whether this generator is constructed at program start or first
use. I do not forsee ever using another generator.

Ok, I guess our requirements are very different. I don't understand why you would need to force there to only ever be one instance, certainly not to the extent where you go and write code to enforce it.

2) generator is seeded upon construction.

But where does this happen, with your design it is not always guaranteed to be in the same place.

Once seeded, for further
calls to the generator instance providing a seed, that seed should be
ignored/the generator should not be reseeded. This is what my code
currently does

Is repeatability of experiments not an issue for you? If you want to repeat runs then you need to know what the seed value is before you start drawing numbers from the generator, and you also need to be able to set it before any numbers are drawn. At what point do you set the seed?

3) Right now, i do not forsee the need of generating random numbers
before main has been called. However, I am interested in knowing what
the problem would be in trying to use my class before main has been
called, I have never dealt with such problems and would appreciate a
kick in the right direction so I can learn something about it.

What I was trying to get at is that if you are intending to seed the generator with a specific value, then this can't really happen until main(). However if you have a global object whose constructor draws some numbers from the generator, then it will do so before the seed is set, this is clearly bad.

4) will not be used in multithreaded environment. If it ever would be,
I would like all threads to use the same generator instance. Is that
what will happen now? (I know I would then also have to worry about
race conditions, but lets not get into that now).

The multithreaded problem is a real pain, the issue once again is repeatability. If thread A and B are both requesting a number, then there is no deterministic guarantee about which thread will manage to lock the appropriate mutex first, and so over multiple executions, the same threads will not get the same numbers.


I have looked it up, thank you for the suggestion. I, however do not
see the advantage of wrapping the generator.

Well you are wrapping up the variate_generator yourself with your specializations of the CRandom template. My suggestion is that instead of your CRandom class, you just return the variate_generator inside a boost function.
 
Also, how does your
approach assure that the same engine is always used and that this
enigine is never destructed once constructed before program end 

The shared_ptr is a static variable in an object file, it is only accessible by functions. The set function will only allow it to be set once. A reference to the generator is obtained by calling a global function and it will always return the same thing (assuming it has been allocated). Destruction will occur whenever the operating system destroys global objects. I have no idea when that is, and it is most likely very platform dependent, however it will always be long after main has returned.

(i see
you are using a shared pointer, I assume it would destruct the engine
when all references went out of scope)?

There should only ever be two shared_ptrs point to the generator, the first is the one that holds the instance I create, the second is the static global variable. Whenever I create a variate_generator, it does NOT pass any shared_ptrs around or alter any reference counts, it just passes the address of the actual generator. That's because I know the global variable will keep the generator in scope for all the time that I am in main() and thus the entre scope of the variate_generator.

I now have a compact class
that also ensures i cannot forget to seed my engine as that is done in
the constructor.

Does it make sure you can't forget to seed it, or does it automatically seed it with time(), there is a difference.


I just tested this, and Instance() and Instance(unsigned int) indeed
return different objects (different memory address), so this is an
issue. How do I get around this, I want only one instance of
boost::mt19937 to be instantiated, no matter whether any argument or
what type of argument is supplied to Instance(). Should i use a Gamma
Singleton for that (if (!m_pInstance) m_pInstance=new T; return
*m_pInstance;)?

Sorry, I don't know what a Gamma Singleton is, if you haven't gathered yet I'm a little anti-singleton. I think it's a far too overused, not particularly useful pattern.

To solve this issue you need the object that is the focus of the singleton to only exist in one place. Off the top of my head I would suggest a static class variable which points to the object in question.

Thanks,
Kevin Martin