2012-12-24 13 views
7

Używam GCC 4.6.3 i próbował generować liczby losowe z następującego kodu:C++ 11 liczb losowych i std :: wiążą współdziałać w nieoczekiwany sposób

#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; 
} 

spodziewałem obie metody do generowania sekwencja 5 liczb losowych. Zamiast tego, tak właśnie otrzymuję:

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

Czy jest to błąd GCC? Czy jest to jakiś subtelny problem związany ze std :: bind? Jeśli tak, to czy możesz mieć jakiś sens wyniku?

Dzięki.

Odpowiedz

11

Po związaniu tworzona jest kopia rng_engine. Jeśli chcesz przekazać odwołanie, to co trzeba zrobić:

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

nie fair, miałem rozmowę z mamą przed wysłaniem +1 dla prędkość. – nurettin

+2

Cholera, nie mogę po prostu odpowiedzieć z uśmiechem :) –

+0

Nieco poza tematem, ale co jeśli chcesz użyć bindowania i przekazać generator przez odniesienie do każdego std :: thread? – pyCthon

5

std::uniform_real_distribution::operator() trwa Generator & więc trzeba będzie związać za pomocą std :: REF

#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() jest dla powtórzony używa.

Umieszczenie go na zewnątrz pętli ...

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()); 
} 

... daje mi oczekiwany wynik:

0.135477 
0.835009 
0.968868 
0.221034 
0.308167 
Powiązane problemy