繁体   English   中英

宏中的作用域匿名变量声明

[英]scoped anonymous variable declaration within a macro

我有一个用于记录的宏,在宏中我想定义一个临时记录,如下所示:

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

使用temprecord() { logger->increaseIndent() }并在析构函数中使用 reductionIndent( decreaseIndent()

与名称(例如,变量)的关联给出了控制其生命周期的 object scope。 通过不命名 object,它的生命周期是有限的

为什么未命名的 C++ 对象会在 scope 块结束之前破坏

因为 temprecord 具有 scope 的生命周期,如果我有

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

在 scope 之外,我将有 0 个缩进,在 scope 中,我将有 1 个和 2 个缩进。 但是,当我将 temprecord 命名为 t 时,我会重新定义变量名。如果我不声明它,我不会得到我想要的 scope。

如何 go 关于这个? 我想用一个容器来放临时记录,但似乎无法解决这个难题..

我希望完成的是我提到的 scope 中的双缩进,而不是 MACRO_LOG scope 中的单缩进。

宏替换只是就地文本替换。 因此,鉴于您显示的#define ,代码:

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

扩展为:

{
    temprecord t;
    logger->logmessage("stackoverflow example");;
    temprecord t;
    logger->logmessage("stackoverflow example");;
}

这应该很明显为什么宏在同一个 scope 中多次使用时不起作用,因为t被多次声明。

有一些不同的方法可以解决这个问题:

1) 将MACRO_LOG()的内容用大括号括起来,这样temprecord t就在它自己的 scope 中,例如:

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

这会将代码扩展为:

{
    {
        temprecord t;
        logger->logmessage("stackoverflow example");
    };
    {
        temprecord t;
        logger->logmessage("stackoverflow example");
    };
}

2) append __LINE__ to ttemprecord的每个副本一个更唯一的名称,例如:

(请参阅使用 ## 和 __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()的同一表达式中定义一个无名变量,该变量不会 go 超出 scope 直到logmessage()返回,例如:

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

这会将代码扩展为:

{
    temprecord(), logger->logmessage("stackoverflow example");;
    temprecord(), logger->logmessage("stackoverflow example");;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM