std ::iform_real_distribution регенерирует то же случайное число

При выполнении кода ниже, первая половина arr равняется последней половине Зачем? Я даже пробовал разные семена, например std::chrono::system_clock::now().time_since_epoch().count(), Благодарю.

#include <algorithm>
#include <iostream>
#include <random>template<typename DistributionType>
class Rng
{
public:
template<typename ...Args>
Rng(Args&&... args) : dist(args...) { }

typename DistributionType::result_type operator()()
{
return dist(gen);
}

private:
std::default_random_engine gen;

DistributionType dist;
};class UniformRealRng : public Rng<std::uniform_real_distribution<double>>
{
public:
UniformRealRng(const double a, const double b) : Rng(a, b) { }
};

int main()
{
constexpr int sz = 6;
constexpr int k  = sz / 2;
double arr[sz];

UniformRealRng rng(0.0, 1.0);
std::generate(arr, arr + k, rng);
std::generate(arr + k, arr + sz, rng);

for (int i = 0; i < sz; ++i)
{
std::cout << arr[i];
}
std::cout << "\n";
}

2

Решение

Ваш ответ на самом деле правильный, но не решает проблему.
Он генерирует ошибку компиляции только тогда, когда ошибочно (?) Пытаются скопировать генератор случайных чисел.

Оказывается, что код можно сделать семантически правильным, используя std::reference_wrapper Особенности библиотеки.

    std::generate(arr, arr + k, std::ref(rng));
std::generate(arr + k, arr + sz, std::ref(rng));

Таким образом, вы в основном вынуждены передавать аргумент по ссылке.
к счастью эталонная оболочка перегружает operator() и, следовательно, может быть использован для генератора без какого-либо дополнительного кода.

Полный код:

#include <algorithm>
#include <iostream>
#include <random>
#include <functional> //ref

template<typename DistributionType>
class Rng
{
public:
template<typename ...Args>
Rng(Args&&... args) : dist(args...) { }
//      Rng(Rng&)             = delete;  // this is not needed for it to work
//      Rng& operator=(Rng&)  = delete;  // you MAY want to copy the generator
typename DistributionType::result_type operator()()
{
return dist(gen);
}

private:
std::default_random_engine gen;

DistributionType dist;
};class UniformRealRng : public Rng<std::uniform_real_distribution<double>>
{
public:
UniformRealRng(const double a, const double b) : Rng(a, b) { }
};

int main()
{
constexpr int sz = 6;
constexpr int k  = sz / 2;
double arr[sz];

UniformRealRng rng(0.0, 1.0);
std::generate(arr, arr + k, std::ref(rng));
std::generate(arr + k, arr + sz, std::ref(rng));

for (int i = 0; i < sz; ++i)
{
std::cout << arr[i];
}
std::cout << "\n";
}
0

Другие решения

std::generate принимает третий аргумент по значению, так rng копировался.

В целях безопасности можно удалить копирование:

Rng(Rng&)             = delete;
Rng& operator=(Rng&)  = delete;
3

По вопросам рекламы [email protected]