是否可以使用与此(错误)语法类似的内容进行宏选择?
#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
答案 0 :(得分: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 ++提供了更好的机制(运行时多态,模板等)来解决大多数(但不是全部)这种性质的问题。
答案 1 :(得分:7)
#define ADD +
#define MULT *
//...
#define FLAG MULT
//...
int op(int a, int b) {return a FLAG b;}
答案 2 :(得分: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
要好得多,以避免名称冲突),然后按照任何其他答案中的建议进行操作。
答案 3 :(得分:1)
根据定义的常量,您肯定可以改变marko的行为 f.e
config.h
#define MP
#include "other.h"
other.h
#ifdef MP
#define // your define here
#elif
// other define here
#endif
答案 4 :(得分: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的回答
答案 5 :(得分: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);