2012-12-24 17 views
7

Sto usando GCC 4.6.3 e stava cercando di generare numeri casuali con il seguente codice:C++ 11 numeri casuali e std :: bind interagiscono in modo inaspettato

#include <random> 
#include <functional> 

int main() 
{ 
    std::mt19937 rng_engine; 

    printf("With bind\n"); 
    for(int i = 0; i < 5; ++i) { 
     std::uniform_real_distribution<double> dist(0.0, 1.0); 
     auto rng = std::bind(dist, rng_engine); 
     printf("%g\n", rng()); 
    } 

    printf("Without bind\n"); 
    for(int i = 0; i < 5; ++i) { 
     std::uniform_real_distribution<double> dist(0.0, 1.0); 
     printf("%g\n", dist(rng_engine)); 
    } 

    return 0; 
} 

mi aspettavo entrambi i metodi per generare una sequenza di 5 numeri casuali. Invece, questo è quello che effettivamente ottengo:

With bind 
0.135477 
0.135477 
0.135477 
0.135477 
0.135477 
Without bind 
0.135477 
0.835009 
0.968868 
0.221034 
0.308167 

Si tratta di un bug GCC? O è un problema sottile che ha a che fare con std :: bind? In tal caso, puoi dare un senso al risultato?

Grazie.

risposta

11

Quando si esegue il collegamento, viene creata una copia di rng_engine. Se si vuole passare un riferimento, questo è ciò che devi fare:

auto rng = std::bind(dist, std::ref(rng_engine)); 
+2

Non è giusto, ho avuto una chiamata da mamma prima di pubblicare +1 per velocità. – nurettin

+2

Dannazione, non posso semplicemente rispondere con una faccina :) –

+0

Un po 'fuori tema, ma cosa succede se vuoi usare il bind e passare un generatore per riferimento a ogni std :: thread? – pyCthon

5

Il std::uniform_real_distribution::operator() prende una Generator & in modo da avere a legare con std :: Rif

#include <random> 
#include <functional> 

int main() 
{ 
    std::mt19937 rng_engine; 

    printf("With bind\n"); 
    for(int i = 0; i < 5; ++i) { 
     std::uniform_real_distribution<double> dist(0.0, 1.0); 
     auto rng = std::bind(dist, std::ref(rng_engine)); 
     printf("%g\n", rng()); 
    } 

    printf("Without bind\n"); 
    for(int i = 0; i < 5; ++i) { 
     std::uniform_real_distribution<double> dist(0.0, 1.0); 
     printf("%g\n", dist(rng_engine)); 
    } 
} 
2

bind() è per ripetuto utilizza.

Mettere al di fuori del ciclo ...

std::mt19937 rng_engine; 
std::uniform_real_distribution<double> dist(0.0, 1.0); 
auto rng = std::bind(dist, rng_engine); 

for(int i = 0; i < 5; ++i) { 
    printf("%g\n", rng()); 
} 

... mi dà il risultato atteso:

0.135477 
0.835009 
0.968868 
0.221034 
0.308167