What is the correct way to instantiate C ++ 11

Having examined various examples of using new "random" objects in C ++, I got a little confused about best practices, especially related to the lifetimes of various cases.

For example, in some examples, the use of "random_device" is either static in the local scope, as a function, or is a static global variable, or simply local.

--- TU --- static std::random_device global_source; void foo() { static std::random_device local_static_source; static std::mt19937 gen(local_static_source()); std::uniform_int_distribution<> dist(0,10); ... dist(gen); ... } void boo() { std::mt19937 gen(global_source()); std::uniform_int_distribution<> dist(0,10); ... dist(gen); ... } void roo() { std::random_device local_source; std::mt19937 gen(local_source()); std::uniform_int_distribution<> dist(0,10); ... dist(gen); ... } int main() { static std::mt19937 gen(global_source()); std::uniform_int_distribution<> dist(0,10); ... dist(gen); ... return 0; } --- TU --- 

Q1: If foo or boo can be accessed across multiple threads, is it normal for the generator and source to be static? - Are there any guarantees of thread safety, for example, in shared_ptr?

Q2: Is there any wording in the standard that discusses the assumptions and problems associated with instantiation?

+7
c ++ instantiation random c ++ 11
source share
1 answer

Some prerequisites: the reasons for allowing multiple instances of random number generators are mainly related to thread safety (without burdening the implementation of random number generators with thread synchronization) and repeatability (allowing repeating a sequence of numbers using the same seed).

  • The first of these is pretty clear - there are good cases of using RNG in performance-critical code. With multiple instances, expensive mutexes are not required, and random numbers can be generated on multiple processor cores in parallel.

  • The latter is usually useful when creating datasets at random. As a general example, video games can recreate the same (random) game world, managing all the decisions involved in creating a game world from the same RNG (possibly even on different network computers).

So the best area for C ++ RNG depends on what you write:

If you are writing a library that can be used in the context of the above for scripting, it is probably a good idea for the caller to provide RNG to individual methods or classes:

 // Can be used on multiple CPU cores in parallel or with seed values template <typename TRandomNumberEngine> Point2 GetRandomPointInRectangle( const Rectangle2 &rect, TRandomNumberEngine &random ) { std::uniform_real_distribution<float> horizontal(rect.Min.X, rect.Max.X); float x = horizontal(random); std::uniform_real_distribution<float> vertical(rect.Min.Y, rect.Max.Y); float y = vertical(random); return Point2(x, y); } 

If you are writing an application or library using RNG in a supporting role (for example, geometric fitting algorithms), i.e. you are just interested in random numbers that cannot be reproduced, the best area for a random number generator would be the largest possible area that would not create an undesirable connection between the modules.

It can be a simple private object variable in any class that needs random numbers or even one single thread_local , giving you RNG if it has many short-lived consumers that justify such complexity.


Distributions (e.g. std::uniform_real_distribution ) can be short lived as you want. They are simple functors, where the constructor either has no arguments, or stores only arguments for when the functor will be executed.

+1
source share

All Articles