I am using GCC 4.6.3 and was trying to generate random numbers with the following code:
#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;
}
I expected both methods to generate a sequence of 5 random numbers. Instead, this is what I actually get:
With bind
0.135477
0.135477
0.135477
0.135477
0.135477
Without bind
0.135477
0.835009
0.968868
0.221034
0.308167
Is this a GCC bug? Or is it some subtle issue having to do with std::bind? If so, can you make any sense of the result?
Thanks.
When binding, a copy of rng_engine is made. If you want to pass a reference, this is what you have to do :
auto rng = std::bind(dist, std::ref(rng_engine));
The std::uniform_real_distribution::operator()
takes a Generator &
so you will have to bind using 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));
}
}
bind()
is for repeated uses.
Putting it outside of the loop...
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());
}
... gives me the expected result:
0.135477
0.835009
0.968868
0.221034
0.308167
来源:https://stackoverflow.com/questions/14023880/c11-random-numbers-and-stdbind-interact-in-unexpected-way