我有一个程序使用boost::random的mt19937随机数生成器。我需要执行random_shuffle并希望为此生成的随机数来自此共享状态,以便可以相对于mersenne twister先前生成的数来确定性。
我尝试过这样的事情:
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
struct bar {
boost::mt19937 &_state;
unsigned operator()(unsigned i) {
boost::uniform_int<> rng(0, i - 1);
return rng(_state);
}
bar(boost::mt19937 &state) : _state(state) {}
} rand(state);
std::random_shuffle(vec.begin(), vec.end(), rand);
}
但是我收到一个模板错误,用rand调用random_shuffle。但这有效:
unsigned bar(unsigned i)
{
boost::mt19937 no_state;
boost::uniform_int<> rng(0, i - 1);
return rng(no_state);
}
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
std::random_shuffle(vec.begin(), vec.end(), bar);
}
可能是因为它是实际的函数调用。但是很明显,这并不能阻止原始的梅森纳扭曲者的状态。是什么赋予了?没有全局变量,有什么方法可以做我想做的事情吗?
最佳答案
在C++ 03中,您不能基于函数本地类型实例化模板。如果将rand类移出该函数,它应该可以正常工作(免责声明:未经测试,可能还会有其他危险的错误)。
在C++ 0x中已经放宽了此要求,但是我不知道该更改是否已在GCC的C++ 0x模式中实现,并且如果在其他任何编译器中都可以看到它,我将感到非常惊讶。