2013-09-02 2 views
0

Я пытаюсь написать программу на 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: неожиданные жетоны после директивы препроцессора - ожидается новая строка ». Я провел некоторое исследование и обнаружил, что я не могу использовать оператор области видимости :: в директиве препроцессора, но есть ли способ сделать этот условный компилятор?

EDIT: Я в основном ищу способ использовать одну переменную для нескольких разных enums, как непрозрачный тип данных. Использование #define было самым простым решением. Я использую результирующие настройки таким же образом, поэтому мне не нужно было отслеживать, какое конкретное перечисление я использовал, просто одно имя, с помощью которого можно вызвать любые настройки.

DEPRECATED: Я решил найти другое решение моей проблемы и больше не ищу ответа на этот вопрос.

+1

Значение 'getSettingA()' можно определить только во время выполнения. Как вы ожидаете, что компилятор узнает его во время компиляции - с машиной времени? Кроме того, как вы планируете использовать 'SETTING_TWO' (если вы каким-то образом определили его)? Можете ли вы показать пример? Он может иметь один из нескольких разных типов, в основном непредсказуемо. –

+0

Кроме того, вы полагаетесь на '' #SETTING_TWO '' на '' getSettingB() "и так далее? Слишком неопределенный вопрос по моему вкусу –

+0

@ JohannesSchaub-litb Я использую один и тот же формат для каждого из параметров, но значения в 'enums' отличаются друг от друга. Я не полагаюсь на 'SETTING_TWO' для любого конкретного перечисления, потому что все они используются одинаково. См. Мое редактирование. – Frostfyre

ответ

0

Это неправильно: #if SETTING_ONE == A :: Один

вы не можете сделать это с помощью препроцессора.

С шаблонами я бы попробовал что-то вроде черт.

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*/ 
+0

Я знаю, что код не работает так, как есть. Я ищу способ сделать такую ​​условную компиляцию. – Frostfyre

+0

вы не можете с перечислением. Может быть, шаблон? – dzada

+0

Можете ли вы привести пример с использованием шаблона? – Frostfyre

Смежные вопросы