2012-05-03 3 views
0

Можно ли сделать выбор макроса, используя что-то похожее на этот (неправильный) синтаксис?Выбор макроса

#define FLAG MULT 
#ifdef FLAG ADD 
    int op(int a, int b) {return a + b;} 
#endif 
#ifdef FLAG MULT 
    int op(int a, int b) {return a * b;} 
#endif 
+1

Я думаю, вы имеете в виду '#ifdef FLAG MULT' для второго условия, не так ли? –

+0

Да, спасибо. Я редактировал. – Aslan986

+0

Вы описываете свою цель? Мне любопытно. – Benj

ответ

8

Вы можете сделать это:

#define ADD 0 
#define MULT 1 

#define FLAG MULT 
#if (FLAG == ADD) 
    int op(int a, int b) {return a + b;} 
#elif (FLAG == MULT) 
    int op(int a, int b) {return a * b;} 
#endif 

Однако условная компиляция часто приводит к печали (типично, «неиспользованный» филиал будет в конечном итоге не сопровождается, и вещи будут ломаться, когда вы переключаетесь на использование Это).

C++ предлагает лучшие механизмы (полиморфизм во времени выполнения, шаблоны и т. Д.) Для решения большинства (но не всех) проблем такого характера.

+0

+1, но также можно использовать '# elif' для второго условия. – FatalError

7
#define ADD + 
#define MULT * 
//... 
#define FLAG MULT 
//... 
int op(int a, int b) {return a FLAG b;} 
1

Вы можете, конечно, изменить поведение Marko в зависимости от заданного постоянная ф

config.h 
#define MP 
#include "other.h" 

other.h 
#ifdef MP 
#define // your define here 
#elif 
// other define here 
#endif 
1

Вы можете либо дать макросу значение и проверьте значение, или вы можете изменить имя макроса , То есть:

#define MULT 1 
#define ADD 2 

#define FLAG MULT 
#if (FLAG == ADD) 
    int op(int a, int b) {return a + b;} 
#elif (FLAG == MULT) 
    int op(int a, int b) {return a * b;} 
#endif 

или вы можете сделать:

#define FLAG_MULT 
#ifdef FLAG_ADD 
    int op(int a, int b) {return a + b;} 
#elif defined (FLAG_MULT) 
    int op(int a, int b) {return a * b;} 
#endif 

Я лично предпочитаю ответ hamstergene в

1
#define ADD 0 
#define MULT 1 

#define FLAG MULT 

#if FLAG == ADD 
    int op(int a, int b) {return a + b;} 
#endif 

#if FLAG == MULT 
    int op(int a, int b) {return a * b;} 
#endif 

// ... 

int result = op(2, 3); 
assert(result == 6); 
4

Вы должны стараться избегать макросов как можно больше, и тем более, чтобы генерировать различный код в зависимости от определяет. Это первый шаг на пути, который приводит к разрыву ODR и возникновению неопределенного поведения.

В качестве альтернативы, вы можете рассмотреть только писать различные альтернативы, или с использованием шаблонов (в предположении, что функция имеет больше логики, чем простая операция):

template <typename BinaryFunction> 
int op(int a, int b, BinaryFunction f) { 
    return f(a, b); 
} 
int main() { 
    std::cout << op(5, 3, std::plus<int>()) << std::endl;  // 8 
    std::cout << op(5, 3, std::multiplies<int>()) << std::endl; // 15 
} 

Если вы собираетесь следовать по пути макросов , затем рассмотрите возможность уменьшения объема макросов до минимального минимума (т. е. #undef их, как только они вам не понадобятся), предоставить очень явные и уникальные имена (подумайте над добавлением имени компонента, файла или чего-то подобного, чтобы избежать взаимодействия: #define BINARY_OPERATOR_IMPL_FLAG намного лучше, чем #define FLAG, чтобы избежать столкновений имен), а затем следуйте советам в любом из других ответов.

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