Varia gamma di uniform_int_distribution

Quindi ho un object casuale:

typedef unsigned int uint32; class Random { public: Random() = default; Random(std::mt19937::result_type seed) : eng(seed) {} private: uint32 DrawNumber(); std::mt19937 eng{std::random_device{}()}; std::uniform_int_distribution uniform_dist{0, UINT32_MAX}; }; uint32 Random::DrawNumber() { return uniform_dist(eng); } 

Qual è il modo migliore in cui posso variare (attraverso un’altra funzione o altrimenti) il limite superiore della distribuzione?

(anche disposto a prendere consigli su altri problemi di stile)

Gli oggetti di distribuzione sono leggeri. Costruisci semplicemente una nuova distribuzione quando hai bisogno di un numero casuale. Uso questo approccio in un motore di gioco e, dopo il benchmarking, è paragonabile all’utilizzo del buon vecchio rand() .

Inoltre, ho chiesto come variare la gamma di distribuzione sul live streaming di GoingNative 2013, e Stephen T. Lavavej, membro del comitato standard, ha suggerito di creare semplicemente nuove distribuzioni, in quanto non dovrebbe essere un problema di prestazioni.

Ecco come scriverei il tuo codice:

 using uint32 = unsigned int; class Random { public: Random() = default; Random(std::mt19937::result_type seed) : eng(seed) {} uint32 DrawNumber(uint32 min, uint32 max); private: std::mt19937 eng{std::random_device{}()}; }; uint32 Random::DrawNumber(uint32 min, uint32 max) { return std::uniform_int_distribution{min, max}(eng); } 

Puoi semplicemente creare una std::uniform_int_distribution::param_type e modificare l’intervallo usando il metodo param() . Puoi ridurre il rumore del modello con decltype :

 decltype(uniform_dist.param()) new_range (0, upper); uniform_dist.param(new_range); 

Sto rendendo public funzione DrawNumber per il mio esempio. È ansible fornire un sovraccarico che richiede un limite superiore e quindi passare un nuovo uniform_int_distribution::param_type a uniform_int_distribution::operator()

Il param_type può essere costruito usando gli stessi argomenti della distribuzione corrispondente.

Da N3337, §26.5.1.6 / 9 [rand.req.dist]

Per ciascuno dei costruttori di D assume argomenti corrispondenti ai parametri della distribuzione, P deve avere un costruttore corrispondente sobject agli stessi requisiti e che assume argomenti identici in numero, tipo e valori predefiniti. Inoltre, per ciascuna funzione membro di D che restituisce valori corrispondenti ai parametri della distribuzione, P deve avere una funzione membro corrispondente con nome, tipo e semantica identici.

dove D è il tipo di un object funzione di distribuzione casuale di numeri e P è il tipo nominato dal param_type associato a param_type

 #include  #include  typedef unsigned int uint32; class Random { public: Random() = default; Random(std::mt19937::result_type seed) : eng(seed) {} uint32 DrawNumber(); uint32 DrawNumber(uint32 ub); private: std::mt19937 eng{std::random_device{}()}; std::uniform_int_distribution uniform_dist{0, UINT32_MAX}; }; uint32 Random::DrawNumber() { return uniform_dist(eng); } uint32 Random::DrawNumber(uint32 ub) { return uniform_dist(eng, decltype(uniform_dist)::param_type(0, ub)); } int main() { Random r; std::cout << r.DrawNumber() << std::endl; std::cout << r.DrawNumber(42) << std::endl; }