【发布时间】:2019-01-06 04:39:10
【问题描述】:
所以我对 mersenne_twister 引擎及其功能很感兴趣,所以我决定将初始化它所需的几行代码放在我自己的类中,这样我只需创建该类的一个实例并可以得到我想要的任何范围内的任何随机数,而不必每次需要时都重复这些行。
到目前为止我已经成功了,但是因为我希望我的代码尽可能便携和高效,所以我想根据现有的架构使用 64 位引擎。 我想避免使用编译器定义的预处理器宏的方式,因为这对我来说似乎不是最干净的方法,并且每次我在代码中提到引擎时都需要我使用宏。
我的架构 l 宏如下所示:
#define CPU_ARCH sizeof(nullptr)*8
我在类的私有空间中声明引擎,这样我就可以在构造函数中像这样初始化它:
engine = mt19937(seed);
并像这样在我的随机函数中使用它:
double Random::giveRnd() {
return distribution(engine);
}
现在看起来不错,但我还没有找到一种方法来实现具有相同名称“引擎”的两种架构,以在启动时选择要使用的引擎。
我尝试了以下方法:
-
使用模板创建一个名为 engine 的变量,稍后获取
分配 mt19337 或 mt19337_64 导致编译器
抱怨错误:数据成员“引擎”不能是成员模板
使用以下实现:
class Random {
public:
[...]
private:
template<typename T>
T engine;
[...]
};
- 使用 boost::variant 需要我告诉
我的 giveRnd() 函数在我使用引擎时使用哪种类型 不可能,因为在编译时类型是未知的 - 根本没有在头文件中声明引擎,尽管这 导致 giveRnd() 函数无法使用引擎 因为不在同一个范围内。
-
在头文件中使用预处理器宏,然后在
中使用typeid 找出使用了哪个引擎的源代码,这似乎没有 可能是这样的:如果(CPU_ARCH==32){引擎= mt19337(种子)}
因为编译器不知道引擎永远是
在这种情况下为 32 位,并抱怨我不能使用 '=' 运算符 两种不同的类型。
有没有人知道如何以一种至少有点干净的方式实现这一点?还是我需要依赖预处理器宏?
【问题讨论】:
-
" 每次我在代码中提到引擎时,我都需要使用宏。”为什么?您可以让您的代码使用这些宏来定义您可以根据需要一致引用的其他内容。或者只是有条件地声明一个 using EngineType=
#else using EngineType= ,对吧? -
请提出一个特定的编程问题(代码、目标和您需要帮助的技术障碍)并提供您迄今为止所做工作的代码minimal reproducible example。 Stack Overflow 不适用于代码审查或设计建议。
-
@M.M 你能举例说明如何实现吗?我一般对模板不太熟悉,我不知道为什么需要将其设为静态以及如何在模板中实现 CPU_ARCH。
-
@xaxxon 我不喜欢预定义的宏,因为它们因编译器而异,而且我不能在#if 语句中使用 CPU_ARCH,因为预处理器在编译之前不知道 sizeof(nullptr) 是什么文件。
-
@MM 我明白了,不,我真的不需要它,如果可能只是因为我需要它的罕见机会,那就太酷了,但如果它会使代码复杂化,那就没有必要了太多了。
标签: c++ templates mersenne-twister