它们都是从基类继承的吗?我必须使用模板吗?
(我指的是这些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?
std::random_shuffle(choices_.begin(), choices_.end(), rng);
似乎不起作用。
传递生成器的解决方案:
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); }
};
答案 0 :(得分: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;
}
由于类型扣除,您不需要再使用此模板。
定义一个接受不同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
}
答案 1 :(得分: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);
你并没有真正绕过随机对象,只是一种调用对象operator ()
的方法,但它实现了同样的效果。
请注意,随着std::function
被声明为返回int
,随机数生成器的返回值的精度可能会降低,因此您可能希望使用不同的数据类型而不是int
,取决于您对精度的需求。
答案 2 :(得分:0)
将它包装在符合您需求的课程或仿函数中?
答案 3 :(得分:0)
我建议使用两种方法:函数对象和函数指针。在任何一种情况下,都要使您的类接收函数对象或随机数生成器的函数指针。
使用Function对象,您可以定义基类,并使接收类实现需要指向基函数对象类的指针的函数。这使您可以更自由地定义许多不同的函数对象,而无需更改接收类的接口。