При выполнении кода ниже, первая половина 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";
}
Ваш ответ на самом деле правильный, но не решает проблему.
Он генерирует ошибку компиляции только тогда, когда ошибочно (?) Пытаются скопировать генератор случайных чисел.
Оказывается, что код можно сделать семантически правильным, используя 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";
}
std::generate
принимает третий аргумент по значению, так rng
копировался.
В целях безопасности можно удалить копирование:
Rng(Rng&) = delete;
Rng& operator=(Rng&) = delete;