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
4

6 回答 6

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++ 提供了更好的机制(运行时多态性、模板等)来解决大多数(但不是全部)这种性质的问题。

于 2012-05-03T12:46:12.100 回答
7
#define ADD +
#define MULT *
//...
#define FLAG MULT
//...
int op(int a, int b) {return a FLAG b;}
于 2012-05-03T12:46:17.890 回答
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

于 2012-05-03T12:59:22.310 回答
1

您当然可以根据定义的常量 fe 更改标记的行为

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

other.h
#ifdef MP
 #define // your define here
#elif
 // other define here
#endif
于 2012-05-03T12:47:28.763 回答
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的回答

于 2012-05-03T12:48:52.197 回答
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);
于 2012-05-03T12:49:58.813 回答