Я использую GCC 4.6.3 и пытался сгенерировать случайные числа с помощью следующего кода:
#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;
}
Я ожидал, что оба метода сгенерируют последовательность из 5 случайных чисел. Вместо этого вот что я на самом деле получаю:
With bind
0.135477
0.135477
0.135477
0.135477
0.135477
Without bind
0.135477
0.835009
0.968868
0.221034
0.308167
Это ошибка GCC? Или это какая-то тонкая проблема, связанная с std :: bind? Если да, можете ли вы хоть как-то понять результат?
Благодарю.
При связывании создается копия rng_engine. Если вы хотите передать ссылку, это то, что вам нужно сделать:
auto rng = std::bind(dist, std::ref(rng_engine));
std::uniform_real_distribution::operator()
занимает Generator &
так что вам придется связывать, используя 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()
для многократного использования.
Положив его за пределы цикла …
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());
}
… дает мне ожидаемый результат:
0.135477
0.835009
0.968868
0.221034
0.308167