c++ - pack (type erase) a random number generator -


the c++11 std library has several random number generators (rng), each implementing concept uniformrandomnumbergenerator. these can used argument random distributions, see this documentation overview.

the advantage of design choice of underlying rng engine de-coupled application. however, design requires definition (not merely declarations) of calls rng available (if rng type remain unspecified template parameter). thus, in

struct complicated_random_distribution {   /*      data , auxiliary methods here   */   // complicated; may call rng::operator() many times   template<typename rng>   some_type operator()(rng&gen) const; }; 

the member operator() cannot straightforwardly implemented in separate compilation unit (cu), must available in same header file (or 1 #included it).

for separate implementation, 1 ideally want way pack rng in same way std::function<> packs callable object. (simply using std::function , providing values rng::min() , rng::max() arguments function defined in separate cu restrictive , not allow use, say, std::uniform_real_distribution<> inside).

how can done? implementations available? std library provide in future? or after red herring?


edit random number generators required have static members min() , max(), making type-erasure hard or impossible (gnu's libstdc++ doesn't make assumption , type erasure non-static members min() , max() works, not llvm's libc++, uses standard required static members). there way still solve problem? if not, doesn't imply c++ standard has botched interface random number generators?

adapt rng independent_bits_engine, , type erase adapted rng. have full knowledge of independent_bits_engine's min() , max() are.

here's sketch:

struct rng_wrapper {     using result_type = std::uint32_t;     static constexpr result_type min() { return 0; }     static constexpr result_type max() { return 0xffffffff; }      template<class rng>     using my_engine_type = std::independent_bits_engine<rng, 32, result_type>;      template<class rng,              class = std::enable_if_t<!std::is_same<std::decay_t<rng>, rng_wrapper>{}>>     rng_wrapper(rng&& r)         : rng(my_engine_type<std::decay_t<rng>>(std::forward<rng>(r))) {}      result_type operator()() { return rng(); }     std::function<result_type()> rng; }; 

Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -