передать C ++ распределение случайных чисел в функцию - PullRequest
0 голосов
/ 21 сентября 2018

Я искал похожие вопросы, но не нашел их.Я хочу генерировать нормально распределенные случайные числа.Раньше я кодировал C и немного C ++ 98, но сейчас пытаюсь вернуться и изучить C ++ 11.

У меня есть функция для возврата затравленного RNG

auto seeded_rng () {
      ....  //do seeding.
     std::default_random_engine Eng(/*seeds*/);
     return Eng;
}

Inмоя основная функция - привязать ГСЧ к гауссовскому распределению

auto binded = std::bind(std::normal_distribution<double>{0,1.0},seeded_rng);

. Эта функция работает нормально.Я могу вызвать «binded ()» непосредственно в main, и он генерирует числа

Я хочу иметь объект моделирования, для которого нужно создать случайные числа.Мой вопрос касался того, как передать в «RNG_PART» ниже.

class sim
{
public:
       sim( RNG_PART & rng, int_number_of sims ){ /* Do whatever */}
}

Так что если в основном, я хочу создать объект моделирования

sim A(binded, 100);

, он жалуется.Я пытался объявить

sim::sim(std::default_random_engine &rng, int number_of_sims){}

, но это жалуется.Какой тип я должен использовать, чтобы передать «привязанный» дистрибутив конструктору?Или я делаю это совершенно неправильно.Должен ли я просто объявить двигатель RNG глобально?Я бы предпочел не делать этого.

Извинения, если это очень просто!

1 Ответ

0 голосов
/ 21 сентября 2018

Тип аргумента для sim не соответствует типу binded.Когда вы создаете binded, вы избегаете проблемы, используя auto вместо объявления типа, но вам это понадобится позже.Как насчет следующего в классе sim вместо того, чтобы пытаться выяснить тип заранее.Это также позволяет вам изменять ГСЧ или случайное распределение без изменения класса sim:

template<typename T>
class sim
{    
public:
    sim(T& rng, int_number_of sims ){ /* Do whatever */}

Обратите внимание, что определение шаблона должно быть видимым в месте, где вы его используете, поэтому вы не можете поместить его вфайл cpp, если только этот код не использует его в этом файле.Как правило, определение шаблона находится в том же h-файле, в котором он был объявлен.

Затем вы бы создали sim как:

sim<decltype(binded)> A(binded,100);

decltype(binded) - это способ сказатьшаблон функции sim тип binded.

Поскольку binded может возвращать различные типы в зависимости от выбранного распределения случайных чисел, получение типа возврата в шаблоне класса sim может быть выполнено с помощью

using rnd_return_type = typename std::result_of<T()>::type; //in C++11, C++14

или

using rnd_return_type = std::invoke_result_t<T>; //C++17 and later

std::result_of устарела в C ++ 17 и будет удалена в C ++ 20

...