【问题标题】:pass C++ random number distribution to a function将 C++ 随机数分布传递给函数
【发布时间】:2018-09-21 14:02:09
【问题描述】:

我寻找过类似的问题,但没有找到。我想生成正态分布的随机数。我曾经编写过 C 和一些 C++98 的代码,但现在我想回去学习 C++11。

我有一个返回种子 RNG 的函数

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

在我的主要功能中,我将 RNG 绑定为高斯分布

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

这个功能很好用。我可以直接在 main 中调用“binded()”并生成数字

我想要一个需要创建随机数的模拟对象。我的问题与如何传入下面的“RNG_PART”有关。

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

所以如果在 main 中,我想创建一个模拟对象

sim A(binded, 100);

它抱怨。 我尝试声明

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

但它在抱怨。我应该使用什么类型将“绑定”分布传递给构造函数?还是我完全不正确地解决这个问题。我应该只在全球范围内声明 RNG 引擎吗?我不想那样做。

抱歉,如果这是非常基本的!

【问题讨论】:

  • 您的代码与 C++11 不兼容。在 C++14 中引入了自动函数返回类型推导。此外,您的任务过于复杂。您需要的只是将一些可调用对象传递给您的构造函数,并在需要生成随机数时调用它。因此,您的构造函数的签名可能是例如:sim(std::function&lt;double()&gt; randomNumberGenerator, int numOfSims)。然后只需创建一个不需要任何参数并返回随机双精度的函数(它甚至可能是一些简单的 3 行 lambda)。

标签: c++ c++11 random


【解决方案1】:

sim 的参数类型与绑定的类型不匹配。创建绑定时,您可以通过使用 auto 而不是声明类型来避免该问题,但稍后您将需要它。如何在模拟类中进行以下操作,而不是提前找出类型。这也允许您在不更改 sim 类的情况下更改 RNG 或随机分布:

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 函数模板绑定类型的方法。

由于 bind 可以根据选择的随机数分布返回不同的类型,因此可以在 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 中删除

【讨论】:

  • 酷。谢谢。让我尝试其中的一些东西。我可以在 C++17 中做到这一点。我没有任何限制。只是做一些自学:-)
  • @Ptaq666 在他的评论中也有一种更简单的处理方法。考虑使用模板而不是 std::function&lt;double()&gt; 的一个原因是不同的分布返回不同的值类型(例如,布尔、整数、双精度)。如果你坚持使用 double 作为返回类型,他的版本就可以了。
  • 我意识到 bind 的不同之处在于返回类型,因此无法推断类模板类型——即使在 C++17 中,您也需要在我的示例中使用 decltype。
  • 效果很好。谢谢! (我知道这可能有点矫枉过正,而 lambda 的想法也可以奏效。我不是在尝试解决问题——只是在练习)
猜你喜欢
  • 1970-01-01
  • 2018-12-12
  • 2020-03-12
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 2015-12-26
  • 2015-08-03
  • 2018-11-14
相关资源
最近更新 更多