【问题标题】:Conditional compilation based on previous definition基于前面定义的条件编译
【发布时间】:2013-09-02 17:19:49
【问题描述】:

我正在尝试用 C++11 编写一个基于 enums 的程序来确定主应用程序的值。我知道以下作品:

namespace space
{
    enum class A { One, Two, Three };
}

space::A getSetting();

#define SETTING getSetting()

但是我也想根据第一个设置做一个条件编译来确定第二个设置,比如:

namespace space
{
    enum class A { One, Two, Three };
    enum class B { Red, Blue, Yellow };
    enum class C { Black, White };
    enum class D { Green, Orange };
}

space::A getSettingA();
space::B getSettingB();
space::C getSettingC();
space::D getSettingD();

#define SETTING_ONE getSettingA()
#if SETTING_ONE == A::One
    #define SETTING_TWO getSettingB()
#elif SETTING_ONE == A::Two
    #define SETTING_TWO getSettingC()
#else
    #define SETTING_TWO getSettingD()
#endif

这会提供“C4067:预处理器指令后出现意外标记 - 需要换行符”的编译器警告。我做了一些研究,发现我不能在预处理器指令中使用范围运算符::,但是有没有办法进行这种条件编译?

编辑:我基本上是在寻找一种将一个变量用于几个不同的enums 的方法,比如不透明的数据类型。使用#define 是最简单的解决方案。我以相同的方式使用生成的设置,因此我不想跟踪我正在使用的特定枚举,只需一个名称即可调用任何设置。

已弃用:我已决定为我的问题找到不同的解决方案,并且不再寻求此问题的答案。

【问题讨论】:

  • getSettingA() 的值只能在运行时确定。您如何期望编译器在编译时学习它 - 使用时间机器?另外,您打算如何使用SETTING_TWO(假设您设法以某种方式定义它)?你能举个例子吗?它可能有几种不同类型中的一种,基本上是不可预测的。
  • 另外,你是否依赖"#SETTING_TWO" 成为"getSettingB()" 等等?对我来说太模糊的问题
  • @JohannesSchaub-litb 我对每个设置都使用相同的格式,但enums 中的值与下一个不同。我不依赖 SETTING_TWO 作为任何特定的枚举,因为它们的使用方式相同。请查看我的编辑。

标签: c++11 conditional-compilation


【解决方案1】:

这是错误的:#if SETTING_ONE == A::One

你不能用预处理器做到这一点。

使用模板我会尝试类似特征的东西。

enum{
    One = 58,Two = 54, Red = 65, //...
};
struct A{
    static int value1 = One;
    static int value2 = Two;
};
struct B{
    static int value1 = Red;
    static int value2 = Blue;
};

template <typename T>
struct setting_T{
    static int value1 = T::value1;
    static int value2 = T::value2;
};

typedef setting_T<A> setting; // this is you choice for this compilation (you could use B)

使用它:

setting::value1 /* this is A::value1*/

【讨论】:

  • 我知道代码不能按原样工作。我正在寻找一种方法来进行这种条件编译。
  • 你不能使用枚举。也许是模板?
  • 你能提供一个使用模板的例子吗?
  • 你能告诉我你想如何使用它(在你的代码中)我的意思是这个设置的结果
  • 我希望能够像使用enum 后面的#define 一样使用它。因此,我不使用space::B::Red,而是使用SETTING_TWO,因为SETTING_TWO 可以是三个不同的enums 中的任何一个。然后我使用toString() 函数来获取名称并打开正确的 .xml 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多