STL C++ stl random
нужна лямбда ф-ция генерирующая случаное число stl генератором , нормальное развеивание . минимум -50 макс 50. компилятор подсвечивает gen красным и требует скобку, не понимаю зачем и куда
auto gen = []() {
return std::mt19937 gen{std::random_device()()},
std::uniform_int_distribution<int> uid(-50, 50);
};
Ответы (1 шт):
Полный исправленный код с примером вызова. Генератор и распределение сделал статическими чтобы их не создавать при каждом вызове а пере-использовать созданные один раз. Вместо статических можно вынести их в объемлющую функцию.
#include <random>
#include <iostream>
int main() {
auto gen = []() {
static std::mt19937 rng{std::random_device()()};
static std::uniform_int_distribution<int> distr(-50, 50);
return distr(rng);
};
for (size_t i = 0; i < 10; ++i)
std::cout << gen() << " ";
}
Вывод:
37 10 -49 36 32 20 -32 -40 5 -37
Второй вариант с выносом в объемлющую функцию подходит если эта внешняя функция вызывается редко по сравнению с лямбда функцией. Этот вариант отличается тем что Thread-Safe т.е. безопасен при много-поточности, т.к. static переменные в первом варианте при много-поточности будут конкурировать.
#include <random>
#include <iostream>
int main() {
std::mt19937 rng{std::random_device()()};
std::uniform_int_distribution<int> distr(-50, 50);
auto gen = [&]() {
return distr(rng);
};
for (size_t i = 0; i < 10; ++i)
std::cout << gen() << " ";
}
Ещё один вариант (модификация первого static варианта), решающая проблему многопоточности добавлением мьютекса. Этот вариант медленней, зато может использоваться при многопоточности, в однопоточной среде достаточно первого варианта (первый и быстрее будет).
#include <random>
#include <iostream>
#include <mutex>
int main() {
auto gen = []() {
static std::mt19937 rng{std::random_device()()};
static std::uniform_int_distribution<int> distr(-50, 50);
static std::mutex mux;
std::unique_lock<std::mutex> lock(mux);
return distr(rng);
};
for (size_t i = 0; i < 10; ++i)
std::cout << gen() << " ";
}
Дополнение. Как предложил @ДжонниКэтсвилл, ещё можно использовать спецификатор thread_local, для решения проблемы многопоточности. Т.е. следующий код безопасен в многопоточной среде и не требует использования std::mutex. На мой взгляд это самый лучший из всех 4х предложенных вариантов кода.
#include <random>
#include <iostream>
int main() {
auto gen = []() {
thread_local std::mt19937 rng{std::random_device()()};
thread_local std::uniform_int_distribution<int> distr(-50, 50);
return distr(rng);
};
for (size_t i = 0; i < 10; ++i)
std::cout << gen() << " ";
}