2012-12-24 19 views
7

Tôi đang sử dụng GCC 4.6.3 và đã cố gắng để tạo ra số ngẫu nhiên với đoạn mã sau:C++ 11 số ngẫu nhiên và std :: ràng buộc tương tác một cách bất ngờ

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

tôi mong đợi cả hai phương pháp để tạo ra một chuỗi gồm 5 số ngẫu nhiên. Thay vào đó, đây là những gì tôi thực sự nhận được:

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

Đây có phải là lỗi của GCC không? Hoặc là nó một số vấn đề tinh tế phải làm với std :: bind? Nếu vậy, bạn có thể làm cho bất kỳ ý nghĩa của kết quả?

Cảm ơn.

Trả lời

11

Khi ràng buộc, một bản sao của rng_engine được thực hiện. Nếu bạn muốn vượt qua một tài liệu tham khảo, đây là những gì bạn phải làm:

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

Không công bằng, tôi đã có một cú điện thoại từ mẹ trước khi gửi bài 1 cho tốc độ. – nurettin

+2

Chết tiệt, tôi không thể chỉ trả lời với một nụ cười :) –

+0

Hơi tắt chủ đề, nhưng nếu bạn muốn sử dụng liên kết và truyền một máy phát điện bằng cách tham chiếu đến mỗi std :: thread? – pyCthon

5

Các std::uniform_real_distribution::operator() mất một Generator &, do đó bạn sẽ phải ràng buộc sử dụng 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() là lặp đi lặp lại sử dụng.

Đưa nó bên ngoài vòng lặp ...

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

... mang lại cho tôi những kết quả mong đợi:

0.135477 
0.835009 
0.968868 
0.221034 
0.308167