c++ - 是否可以将未知类型的变量声明为类成员变量?
问题描述
所以我对 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 位的,并抱怨我不能在两种不同的类型上使用 '=' 运算符。
有没有人知道如何以一种至少有点干净的方式使这成为可能?还是我需要依靠预处理器宏?
解决方案
您可以通过制作一个作为模板参数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);
}
推荐阅读
- jquery - 使 tr 与 contenteditable td 一起可重新排序,但也不起作用
- android - 带有 admob_flutter-0.3.4 AdmobFlutterPlugin.kt 的 Flutter Android 编译问题:(46, 33):重载分辨率歧义和类型推断失败
- kubernetes-helm - Helm卸载删除所有区域的资源
- ms-access - msaccess 表单中的列表框过滤器
- python - 在熊猫中连接多个数据帧时出错
- react-vis - 有没有办法处理 React-Vis Crosshair 上的鼠标悬停事件?
- vhdl - VHDL“此处不允许非共享变量声明”
- reactjs - 如何在codesandbox中添加material-ui/Button
- python - 为什么在出现任何错误后不调用 __del__ 方法?
- javascript - 未捕获的类型错误:firebase.firestore().......set 不是 HTMLButtonElement 的函数。