如何将C++ 11随机数生成器传递给函数?
它们是否都从基类继承?我必须使用模板吗?如何将C++ 11随机数生成器传递给函数?
(我指的是这些http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c15319/)
我现在这样做的权利:
typedef std::mt19937 RNG;
然后
class Chooser {
public:
Chooser(RNG& rng, uint n, uint min_choices, uint max_choices):
换句话说,我通过引用RNG 。我将如何通过一个任意的发电机?
此外,我意识到这可能是一个不同的问题,但我如何将发生器传递给STL?
似乎没有工作。
解决方案,通过发电机:
typedef std::ranlux64_base_01 RNG;
typedef std::mt19937 RNGInt;
解决方案传递给STL:
struct STL_RNG {
STL_RNG(RNGInt& rng): gen(rng) {}
RNGInt& gen;
int operator()(int n) { return std::uniform_int<int>(0, n)(gen); }
};
它们并不都是从一个基地继承的(这有点令人惊讶),但它并不重要,因为这不是C++函子的工作方式。
对于单个给定类型的任意RNG,您已经发布了正确的(现在)。
如果你的意思是,我怎么定义函数接受任何随机数发生器作为参数。
template< class RNG > // RNG may be a functor object of any type
int random_even_number(RNG &gen) {
return (int) gen() * 2;
}
由于类型扣除,您不需要使用比此更多的模板。
定义一个函数接受不同的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
}
这真的很不幸,因为这意味着我必须在头文件中包含所有的随机函数。 – 2010-02-11 00:35:55
(但感谢您的回答...) – 2010-02-11 00:36:34
@ Neil:看到我的第二个答案(我只承诺第一段)。我认为这个标准的意图是你选择一个发电机并坚持下去。如果你只想使用'std :: mt19937',那么不需要任何这个...但是你的问题还不清楚。 – Potatoswatter 2010-02-11 00:41:27
包装在一个类或满足您的需求函子?
有没有一种自动化的方式来包装类似于函子的东西? – 2010-02-11 00:17:38
我建议两种方法:函数对象和函数指针。在任何一种情况下,都可以让你的类接收一个函数对象或一个函数指针给随机数生成器。
使用函数对象,您可以定义一个基类,让您的接收类实现需要指向基函数对象类的指针的函数。这使您可以更自由地定义许多不同的功能对象,而无需更改接收类的接口。
什么工作对我来说是使用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);
你不是真的绕过随机对象,只是一个方法调用该对象的operator()
,但达到同样的效果。
请注意,这里的随机数生成器的返回值的精度可能会减少,因为std::function
声明为返回一个int
,所以你可以根据你的需要进行精确使用不同的数据类型,而不是int
。
根据那篇文章,他们已经是仿函数,所以你应该准备好去。有什么问题? – Potatoswatter 2010-02-11 00:26:02
如果我们知道您的目标,我们可能会提供更具体和有用的信息。 – GManNickG 2010-02-11 00:27:37
具体来说,你希望你的生成器是不同的,你得到的'random_shuffle'编译器错误是什么? – Potatoswatter 2010-02-11 00:44:00