所以我对mersenne_twister引擎及其功能感兴趣,因此我决定将初始化它所需的几行代码放在自己的类中,这样我只需创建该类的一个实例,然后可以得到我想要的任意范围内的任何随机数,而不必每次都需要重复这些行。
到目前为止,我已经取得了成功,但是因为我希望我的代码尽可能地可移植和高效,所以我希望根据当前的体系结构使用64位引擎。 我想避免使用由编译器定义的预处理器宏的方法,因为这对我来说似乎不是最干净的方法,并且每次我在代码中提及引擎时,都需要我使用这些宏。
我对架构l的宏看起来像这样:
#define CPU_ARCH sizeof(nullptr)*8
然后在类的私有空间中声明引擎,以便可以在构造函数中将其初始化,如下所示:
engine = mt19937(seed);
并在我的随机函数中使用它,如下所示:
double Random::giveRnd() {
return distribution(engine);
}
现在看起来还不错,但是我还没有找到一种方法来实现两种具有相同名称“ engine”的体系结构,即在启动时选择要使用的引擎。
我尝试了以下操作:
使用模板创建一个名为engine的变量,该变量稍后会被获取
分配了mt19337或mt19337_64,这会导致编译器
抱怨
错误:数据成员'engine'不能是成员模板
具有以下实现方式:
class Random {
public:
[...]
private:
template<typename T>
T engine;
[...]
};
在头文件中使用预处理器宏,然后在
中使用typeid
查找未使用哪个引擎的源代码
可能是这样的:
if(CPU_ARCH == 32){engine = mt19337(seed)}
因为编译器不知道引擎将永远是
在这种情况下为32位,并且抱怨我不能使用'='运算符
两种不同的类型。
有人对如何以至少一种干净的方式使之成为可能有想法吗?还是我需要依靠预处理器宏?
答案 0 :(得分:0)
您可以通过创建一个以CPU_BITS
作为模板参数并且专门用于期望值的类模板来实现依赖于CPU_BITS
的行为。例如:
#include <random>
template<size_t N> struct CpuOpts;
template<> struct CpuOpts<32> { using EngineType = std::mt19937; };
template<> struct CpuOpts<64> { using EngineType = std::mt19937_64; };
enum { CPU_BITS = sizeof(nullptr)*8 };
using CurrentCpuOpts = CpuOpts<CPU_BITS>;
struct Random
{
CurrentCpuOpts::EngineType engine;
};
int main()
{
Random r;
r.engine.seed(123456);
}