Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以将未知类型的变量声明为类成员变量?_C++_Templates_Mersenne Twister - Fatal编程技术网

C++ 是否可以将未知类型的变量声明为类成员变量?

C++ 是否可以将未知类型的变量声明为类成员变量?,c++,templates,mersenne-twister,C++,Templates,Mersenne Twister,所以我对mersenne_twister引擎及其功能很感兴趣,所以我决定将初始化它所需的几行代码放在我自己的类中,这样我只需创建该类的一个实例,就可以获得任意范围内的任意随机数,而无需在每次需要时重复这些代码行 到目前为止,我已经取得了成功,但因为我希望我的代码尽可能具有可移植性和高效性,我希望根据现有的体系结构使用64位引擎。 我希望避免使用由编译器定义的预处理器宏,因为这对我来说似乎不是最干净的方法,而且每次我在代码中提到引擎时都需要使用宏 架构l的宏如下所示: #define CPU_AR

所以我对mersenne_twister引擎及其功能很感兴趣,所以我决定将初始化它所需的几行代码放在我自己的类中,这样我只需创建该类的一个实例,就可以获得任意范围内的任意随机数,而无需在每次需要时重复这些代码行

到目前为止,我已经取得了成功,但因为我希望我的代码尽可能具有可移植性和高效性,我希望根据现有的体系结构使用64位引擎。
我希望避免使用由编译器定义的预处理器宏,因为这对我来说似乎不是最干净的方法,而且每次我在代码中提到引擎时都需要使用宏

架构l的宏如下所示:

#define CPU_ARCH sizeof(nullptr)*8
engine = mt19937(seed);
double Random::giveRnd() {
    return distribution(engine);
}
我在类的私有空间中声明引擎,以便在构造函数中初始化它,如下所示:

#define CPU_ARCH sizeof(nullptr)*8
engine = mt19937(seed);
double Random::giveRnd() {
    return distribution(engine);
}
在我的随机函数中使用它,如下所示:

#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;

      [...]
};
类随机{
公众:
[...]
私人:
模板
T型发动机;
[...]
};
  • 使用boost::variant需要我告诉
    我的giveRnd()函数在使用引擎时要使用哪种类型 不可能,因为类型在编译时未知
  • 根本不在头文件中声明引擎,尽管 导致giveRnd()函数无法使用引擎 因为它不在同一范围内
  • 在头文件中使用预处理器宏,然后在
    源代码,以找出哪个引擎被使用,这似乎不是 要做到这一点:

    #define CPU_ARCH sizeof(nullptr)*8
    
    engine = mt19937(seed);
    
    double Random::giveRnd() {
        return distribution(engine);
    }
    
    如果(CPU_ARCH==32){engine=mt19337(seed)}

    因为编译器不知道引擎将始终是
    在本例中为32位,并抱怨无法使用“=”运算符 在两种不同的类型上


有没有人知道如何至少以一种干净的方式实现这一点?或者我需要使用预处理器宏吗?

您可以通过创建一个类模板来实现依赖于
CPU\u位的行为,该类模板将
CPU\u位作为模板参数,并专门用于预期值。例如:

#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);
}
#包括
模板结构CpuOpts;
模板结构CpuOpts{using EngineType=std::mt19937;};
模板结构CpuOpts{using EngineType=std::mt19937_64;};
枚举{CPU_位=sizeof(nullptr)*8};
使用CurrentCpuOpts=CpuOpts;
结构随机
{
CurrentCpuOpts::EngineType引擎;
};
int main()
{
随机r;
r、 种子(123456);
}

“每次我在代码中提到引擎时都需要使用宏。”为什么?您可以让您的代码使用这些宏来定义其他可以根据需要一致引用的内容。或者只是有条件地声明一个using EngineType=#else using EngineType=,对吗?请提出一个特定的编程问题(代码、目标和您需要帮助的技术障碍),并提供您迄今为止所做工作的代码。堆栈溢出不用于代码检查或设计建议。@M.M您能举个例子说明如何实现它吗?一般来说,我对模板不太熟悉,我不明白为什么必须将其设置为静态,以及如何在模板中实现CPU_ARCH。@xaxxon我不喜欢预定义的宏,因为它们随编译器而异,并且我不能在#if语句中使用CPU_ARCH,因为预处理器不知道大小(nullptr)是在编译文件之前。@M.M我明白了,不,我真的不需要它,如果有机会我需要它,那就太好了,但是如果它会使代码变得太复杂,那就没有必要了。在谷歌搜索了一些原因之后:D我只做了一次修改,就成功地在我的类中实现了它,移除
Engine::type Engine周围的
struct Random
只是简化了一点点,或者除了可读性之外,还有其他特定的原因吗?
engine.seed
是否等同于
engine(seed)
?除此之外,这非常适合我的目的,非常感谢您为我节省了几个小时的时间:D@TheSupremeGod您的原始代码中有
Random
类。是的,调用
seed
函数相当于在创建时播种。好吧,在我盲目地将您从
引擎
CpuOpts
的编辑带到我的代码中并上床睡觉试图弄清楚Opts的意思之前,您能告诉我吗?抱歉成为世界上最挑剔的程序员:D