包装生成随机数的函数的最简单和最优雅的方法是什么?

mbl*_*mbl -1 c++ c++17

函数如下:

float random_float(float min, float max)
{
    std::random_device rd;                                            // obtain a random number from hardware
    std::mt19937 gen(rd());                                           // seed the generator
    std::uniform_real_distribution<> distr((double)min, (double)max); // define the range
    return (float)distr(gen);
}
Run Code Online (Sandbox Code Playgroud)

我想避免每次调用此函数时调用前 3 行。我也不想用构造函数创建一个类,然后每次我只想生成一个随机数时都必须实例化它。我不太熟悉现代 C++ 特性的可能性,所以我想要一些想法。

Ted*_*gmo 7

您的函数每次被调用时都会生成一个新的随机数生成器。您通常应该只播种一次(每个线程),因为播种 PRNG 需要时间,而且通常没有任何意义重新播种它。

最小的重写:

#include <random>
#include <type_traits>

auto& generator() { // reuse for ALL random_float-like functions
    // make it thread_local if you have more than one thread using it:
    static std::mt19937 gen(std::random_device{}());
    return gen;
}

template<typename T>
std::enable_if_t<std::is_floating_point_v<T>, T> 
random_float(T min, T max)
{
    std::uniform_real_distribution<T> distr(min, max);
    return distr(generator());
}

template<typename T>
std::enable_if_t<std::is_integral_v<T>, T> 
random_int(T min, T max)
{
    std::uniform_int_distribution<T> distr(min, max);
    return distr(generator());
}
Run Code Online (Sandbox Code Playgroud)

要仅实例化一个分发对象(每个所需的分发),您可以添加:

template<float min, float max> // C++20 required (and doesn't work in clang yet)
auto random_float_with_static_distribution() {
    // this also needs to be thread_local if you plan on using it in multiple threads:
    static std::uniform_real_distribution<float> distr(min, max);
    return distr(generator());
}
Run Code Online (Sandbox Code Playgroud)