如何将C++ 11随机数生成器传递给函数?

Nei*_*l G 17 c++ random c++11

它们都是从基类继承的吗?我必须使用模板吗?

(我指的是这些http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c15319/)

我现在正在这样做:

typedef std::mt19937 RNG;
Run Code Online (Sandbox Code Playgroud)

然后

class Chooser {
public:
    Chooser(RNG& rng, uint n, uint min_choices, uint max_choices):
Run Code Online (Sandbox Code Playgroud)

换句话说,我正在传递对RNG的引用.我如何通过任意发电机?

此外,我意识到这可能是一个不同的问题,但我如何将生成器传递给STL?

std::random_shuffle(choices_.begin(), choices_.end(), rng);
Run Code Online (Sandbox Code Playgroud)

似乎不起作用.


通过发电机的解决方案

typedef std::ranlux64_base_01 RNG;
typedef std::mt19937 RNGInt;
Run Code Online (Sandbox Code Playgroud)

传递给STL的解决方案:

struct STL_RNG {
    STL_RNG(RNGInt& rng): gen(rng) {}       
    RNGInt& gen;
    int operator()(int n) { return std::uniform_int<int>(0, n)(gen); }
};
Run Code Online (Sandbox Code Playgroud)

Pot*_*ter 14

它们并非都从一个基础继承(这有点令人惊讶),但它并不重要,因为这不是C++仿函数的工作方式.

对于单个给定类型的任意RNG,您可以(现在)发布它.

如果您的意思是,我如何定义一个接受任何随机数生成器作为参数的函数.

template< class RNG > // RNG may be a functor object of any type
int random_even_number( RNG &gen ) {
    return (int) gen() * 2;
}
Run Code Online (Sandbox Code Playgroud)

由于类型扣除,您不需要使用除此之外的任何模板.


定义一个接受不同RNG的函数是棘手的,因为语义上需要具有公共基类型.您需要定义基本类型.

struct RNGbase {
    virtual int operator() = 0;
    virtual ~RGNBase() {};
};

template< class RNG >
struct SmartRNG : RNGBase {
    RNG gen;

    virtual int operator() {
        return gen();
    }
};

int random_even_number( RNGBase &gen ) { // no template
    return (int) gen() * 2; // virtual dispatch
}
Run Code Online (Sandbox Code Playgroud)

  • 你可以使用`boost :: any`. (2认同)

Mal*_*ous 6

对我有用的是使用std::function:

#include <functional>
#include <random>

void exampleFunction(std::function<int()> rnd) {
    auto randomNumber = rnd();
}

std::minstd_rand rnd;
exampleFunction([&rnd](){ return rnd(); });

// This won't work as it passes a copy of the object, so you end up with the same
// sequence of numbers on every call.
exampleFunction(rnd);
Run Code Online (Sandbox Code Playgroud)

你并没有真正传递随机对象,只是一种调用对象的方法operator (),但它实现了同样的效果.

请注意,这里随机数生成器的返回值的精度可能会因为std::function声明为返回a 而减小int,因此您可能希望使用不同的数据类型,而不是int根据您的精度需求.