我有一个用于记录的宏,我想在该宏中定义一个temprecord,如下所示。
#define MACRO_LOG(...) \
temprecord t; \
logger->logmessage(__VA_ARGS___);
用 temprecord() { logger->increaseIndent() }
并在销毁器中加入 decreaseIndent()
.
与名称(例如,变量)的关联给出了一个控制其寿命的对象范围。如果不给对象命名,它的寿命就会被约束在
因为temprecord有作用域的寿命,如果我有了
{
MACRO_LOG("stackoverflow example");
MACRO_LOG("stackoverflow example");
}
在范围外,我将有0个缩进,在范围内有1和2个缩进。但是当我命名我的temprecord t时,我得到了一个重新定义的变量名称......如果我不声明它,我不会得到我想要的范围。
如何解决这个问题?我想过使用一个容器来放置temprecords,但似乎无法解决这个难题。
我希望实现的是在我提到的范围内的双缩进,而不是在MACRO_LOG范围内的单缩进。
宏替换只是一个原地的文本替换。 所以,给定 #define
你所显示的,代码。
{
MACRO_LOG("stackoverflow example");
MACRO_LOG("stackoverflow example");
}
展开到这里
{
temprecord t;
logger->logmessage("stackoverflow example");;
temprecord t;
logger->logmessage("stackoverflow example");;
}
这应该可以解释为什么宏在同一范围内多次使用时不工作,因为... ... t
被多次声明。
有一些不同的方法可以解决这个问题。
1) 将 MACRO_LOG()
大括号 temprecord t
是在它自己的范围内,例如
#define MACRO_LOG(...) { \
temprecord t; \
logger->logmessage(__VA_ARGS___); \
}
这样就可以把代码扩展为:
{
{
temprecord t;
logger->logmessage("stackoverflow example");
};
{
temprecord t;
logger->logmessage("stackoverflow example");
};
}
2) 附加 __LINE__
到 t
给每个人发一份 temprecord
一个更独特的名字,例如
(见 用##和__LINE__创建C语言宏(用定位宏进行标记连接))
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define MACRO_LOG(...) \
temprecord TOKENPASTE2(t_, __LINE__); \
logger->logmessage(__VA_ARGS___);
这样就可以把代码扩展成这样。
{
temprecord t_12345;
logger->logmessage("stackoverflow example");;
temprecord t_12347;
logger->logmessage("stackoverflow example");;
}
3) 使用 逗号符 定义一个 无名 变量的表达式中,调用 logmessage()
变量不会离开范围,直到 logmessage()
返回,例如。
#define MACRO_LOG(...) temprecord(), logger->logmessage(__VA_ARGS___);
这将扩展代码为:
{
temprecord(), logger->logmessage("stackoverflow example");;
temprecord(), logger->logmessage("stackoverflow example");;
}