Macro selection

Macro selection

本文关键字:selection Macro      更新时间:2023-10-16

是否可以使用类似于这种(错误)语法的东西进行宏选择?

#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

你可以这样做:

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

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

您应该尽量避免宏,更应该根据定义生成不同的代码。这是导致破坏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要好得多以避免名称冲突),然后遵循任何其他答案中的建议。

您肯定可以根据定义的常量更改 marko 的行为F.E

config.h
#define MP
#include "other.h"
other.h
#ifdef MP
 #define // your define here
#elif
 // other define here
#endif
#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);

您可以为宏指定一个值并检查该值,也可以更改宏名称。那是:

#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

我个人更喜欢仓鼠基因的答案