是否可以使用类似于此(错误)语法的方法进行宏选择?
#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 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
您当然可以根据定义的常量 fe 更改标记的行为
config.h
#define MP
#include "other.h"
other.h
#ifdef MP
#define // your define here
#elif
// other define here
#endif
您可以给宏一个值并检查该值,也可以更改宏名称。那是:
#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的回答
#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);