在宏中声明范围内的匿名变量

问题描述 投票:0回答:1

我有一个用于记录的宏,我想在该宏中定义一个temprecord,如下所示。

#define MACRO_LOG(...)             \
temprecord t;                      \
logger->logmessage(__VA_ARGS___); 

temprecord() { logger->increaseIndent() } 并在销毁器中加入 decreaseIndent().

与名称(例如,变量)的关联给出了一个控制其寿命的对象范围。如果不给对象命名,它的寿命就会被约束在

源头 为什么未命名的C++对象在作用域块结束前就会被销毁?

因为temprecord有作用域的寿命,如果我有了

{
   MACRO_LOG("stackoverflow example");
   MACRO_LOG("stackoverflow example");
}

在范围外,我将有0个缩进,在范围内有1和2个缩进。但是当我命名我的temprecord t时,我得到了一个重新定义的变量名称......如果我不声明它,我不会得到我想要的范围。

如何解决这个问题?我想过使用一个容器来放置temprecords,但似乎无法解决这个难题。

我希望实现的是在我提到的范围内的双缩进,而不是在MACRO_LOG范围内的单缩进。

c++ variables scope macros anonymous
1个回答
1
投票

宏替换只是一个原地的文本替换。 所以,给定 #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");;
}
© www.soinside.com 2019 - 2024. All rights reserved.