在C ++ 中,是否可以在嵌套if语句中创建多语句宏,如下所示?我已经尝试了一段时间了,我得到了第二个if语句无法看到' symbol '的范围问题。也许我需要进一步了解宏。
#define MATCH_SYMBOL( symbol, token)
if(something == symbol){
if( symbol == '-'){
}else if (symbol != '-'){
}
other steps;
}
答案 0 :(得分:11)
对于多行宏,你需要在最后一行的末尾添加一个\
字符,告诉宏处理器继续解析下一行的宏,如下所示:
#define MATCH_SYMBOL( symbol, token) \
if(something == symbol){ \
if( symbol == '-'){ \
}else if (symbol != '-'){ \
} \
other steps; \
}
现在,它正试图将其解释为1行宏,然后将一些实际代码解释为文件顶部,这不是您想要的:
#define MATCH_SYMBOL( symbol, token)
// and then... wrongly thinking this is separate...
if(something == symbol){ // symbol was never defined, because the macro was never used here!
if( symbol == '-'){
}else if (symbol != '-'){
}
other steps;
}
答案 1 :(得分:8)
如果你正在使用C ++,你应该完全避免使用宏。它们不是类型安全的,它们不是名称空间感知的,它们很难调试,只是它们非常混乱。
如果您需要与类型无关的功能,请使用模板:
template <typename T>
bool match_symbol(T symbol, T token) {
if(something == symbol){
if( symbol == '-'){
}else if (symbol != '-'){
}
...
或参数可以是不同的类型:
template <typename T, typename V>
bool match_symbol(T symbol, V token) {
if(something == symbol){
if( symbol == '-'){
}else if (symbol != '-'){
}
...
答案 2 :(得分:4)
请注意,此处的部分答案存在问题。
例如,对于正常语句,您可以这样做:
if (foo)
function();
else
otherstuff();
如果您在此处遵循了一些建议,但如果使用宏替换function
,则可能会扩展为:
if (foo)
if (something) { /* ... */ }
else { /* ... */ }; // <-- note evil semicolon!
else
otherstuff();
因此,人们为避免这种情况而采取的常见(丑陋)黑客行为是:
#define MATCH_SYMBOL(symbol, token) \
do \
{ \
if(something == symbol) \
{ \
if( symbol == '-') \
{ \
} \
else if (symbol != '-') \
{ \
} \
other steps; \
} \
} \
while (0) // no semicolon here
这样,“语句”MATCH_SYMBOL(a, b)
可以像正常语句一样以分号结尾。你还可以在多个陈述中使用大括号。
如果你认为没有人疯狂地使用这种技术,那就再想一想。例如,它在Linux内核中很常见。
答案 3 :(得分:1)
你需要在宏的所有行的末尾加上反斜杠(\),但最后一行。
答案 4 :(得分:1)
C ++的方式:
inline void MATCH_SYMBOL(const Symbol& symbol, const Token& token) {
/* ... */
if (something == symbol) {
if ('-' == symbol) {
/* ... */
}
else if ('-' != symbol) {
/* ... */
}
}
/* ...other steps... */
}
答案 5 :(得分:0)
另外,看看是否可以用函数替换宏。
?
MATCH_SYMBOL(Sym const & symbol, Tok const & token)
{
...
}
答案 6 :(得分:0)
还可以定义宏功能并实现功能而不是
#define MATCH_SYMBOL( symbol, token) match_symbol(symbol,token)