是否可以将未知类型的变量声明为 class 成员变量?
Is it possible to declare a variable of unknown type as a class member variable?
所以我对 mersenne_twister 引擎及其功能很感兴趣,所以我决定将初始化它所需的几行代码放在我自己的 class 中,这样我只需创建一个 class 的实例,就可以获得我想要的任何范围内的任何随机数,而不必在每次需要时都重复这些行。
到目前为止我已经成功了,但是因为我希望我的代码尽可能地便携和高效,所以我想根据现有的体系结构使用 64 位引擎。
我想避免使用编译器定义的预处理器宏的方式,因为这对我来说似乎不是最干净的方法,而且每次我在代码中提到引擎时也需要我使用宏。
我的架构 l 宏如下所示:
#define CPU_ARCH sizeof(nullptr)*8
然后我在 class 的私有 space 中声明引擎,这样我就可以在构造函数中像这样初始化它:
engine = mt19937(seed);
并像这样在我的随机函数中使用它:
double Random::giveRnd() {
return distribution(engine);
}
这现在看起来不错,但我还没有找到一种方法来实现具有相同名称的两种架构 "engine" 以在启动时选择要使用的引擎的方式。
我尝试了以下操作:
使用模板创建名为 engine 的变量,稍后获取
分配 mt19337 或 mt19337_64 导致编译器
抱怨
错误:数据成员'engine'不能是成员模板
实施如下:
class Random {
public:
[...]
private:
template<typename T>
T engine;
[...]
};
- 使用boost::variant需要我告诉
我的 giveRnd() 函数在我使用引擎时使用哪种类型
不可能,因为编译时类型未知
- 虽然这样,但根本没有在头文件中声明引擎
导致 giveRnd() 函数无法使用引擎
因为不在同一个范围内。
在头文件中使用预处理器宏,然后在
中使用typeid
找出使用了哪个引擎的源代码,这似乎不是
可能是这样的:
if(CPU_ARCH==32) { engine = mt19337(seed) }
因为编译器不知道引擎会一直
在这种情况下是 32 位,并抱怨我不能使用“=”运算符
在两种不同的类型上。
有没有人知道如何以一种至少有点干净的方式使这成为可能?还是我需要求助于预处理器宏?
您可以通过制作一个 class 模板来实现依赖于 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);
}
所以我对 mersenne_twister 引擎及其功能很感兴趣,所以我决定将初始化它所需的几行代码放在我自己的 class 中,这样我只需创建一个 class 的实例,就可以获得我想要的任何范围内的任何随机数,而不必在每次需要时都重复这些行。
到目前为止我已经成功了,但是因为我希望我的代码尽可能地便携和高效,所以我想根据现有的体系结构使用 64 位引擎。 我想避免使用编译器定义的预处理器宏的方式,因为这对我来说似乎不是最干净的方法,而且每次我在代码中提到引擎时也需要我使用宏。
我的架构 l 宏如下所示:
#define CPU_ARCH sizeof(nullptr)*8
然后我在 class 的私有 space 中声明引擎,这样我就可以在构造函数中像这样初始化它:
engine = mt19937(seed);
并像这样在我的随机函数中使用它:
double Random::giveRnd() {
return distribution(engine);
}
这现在看起来不错,但我还没有找到一种方法来实现具有相同名称的两种架构 "engine" 以在启动时选择要使用的引擎的方式。
我尝试了以下操作:
使用模板创建名为 engine 的变量,稍后获取
分配 mt19337 或 mt19337_64 导致编译器
抱怨错误:数据成员'engine'不能是成员模板
实施如下:
class Random {
public:
[...]
private:
template<typename T>
T engine;
[...]
};
- 使用boost::variant需要我告诉
我的 giveRnd() 函数在我使用引擎时使用哪种类型 不可能,因为编译时类型未知 - 虽然这样,但根本没有在头文件中声明引擎 导致 giveRnd() 函数无法使用引擎 因为不在同一个范围内。
在头文件中使用预处理器宏,然后在
中使用typeid 找出使用了哪个引擎的源代码,这似乎不是 可能是这样的:if(CPU_ARCH==32) { engine = mt19337(seed) }
因为编译器不知道引擎会一直
在这种情况下是 32 位,并抱怨我不能使用“=”运算符 在两种不同的类型上。
有没有人知道如何以一种至少有点干净的方式使这成为可能?还是我需要求助于预处理器宏?
您可以通过制作一个 class 模板来实现依赖于 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);
}