简体   繁体   English

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

[英]scoped anonymous variable declaration within a macro

I have a macro which I use to log, and within the macro I'd like to define a temprecord as follows:我有一个用于记录的宏,在宏中我想定义一个临时记录,如下所示:

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

with temprecord() { logger->increaseIndent() } and in the destructor a decreaseIndent() .使用temprecord() { logger->increaseIndent() }并在析构函数中使用 reductionIndent( decreaseIndent()

The association with a name (eg, variable) gives an object scope which controls its lifetime.与名称(例如,变量)的关联给出了控制其生命周期的 object scope。 By not naming an object, it's lifetime is bound通过不命名 object,它的生命周期是有限的

source Why do un-named C++ objects destruct before the scope block ends? 为什么未命名的 C++ 对象会在 scope 块结束之前破坏

Because the temprecord has lifetime of the scope, if I have因为 temprecord 具有 scope 的生命周期,如果我有

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

Outside the scope I will have 0 indent and in the scope 1 and 2 indents.在 scope 之外,我将有 0 个缩进,在 scope 中,我将有 1 个和 2 个缩进。 However , as I name my temprecord t I get a redefinition of variable names.. and if I do not declare it I do not get the scope that I want.但是,当我将 temprecord 命名为 t 时,我会重新定义变量名。如果我不声明它,我不会得到我想要的 scope。

How to go about this?如何 go 关于这个? I thought of using a container to put the temprecords in, but can't seem to solve the puzzle..我想用一个容器来放临时记录,但似乎无法解决这个难题..

What I wish to accomplish is double indentation in my mentioned scope, and not single indentation within the MACRO_LOG scope.我希望完成的是我提到的 scope 中的双缩进,而不是 MACRO_LOG scope 中的单缩进。

Macro replacement is just an in-place text replacement.宏替换只是就地文本替换。 So, given the #define you have shown, the code:因此,鉴于您显示的#define ,代码:

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

Expands to this:扩展为:

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

Which should make it obvious why the macro doesn't work when used multiple times in the same scope, since t is declared multiple times.这应该很明显为什么宏在同一个 scope 中多次使用时不起作用,因为t被多次声明。

There are some different ways you can solve this:有一些不同的方法可以解决这个问题:

1) wrap the content of MACRO_LOG() in curly braces so that temprecord t is in its own scope, eg: 1) 将MACRO_LOG()的内容用大括号括起来,这样temprecord t就在它自己的 scope 中,例如:

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

Which would expand the code to this:这会将代码扩展为:

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

2) append __LINE__ to t to give each copy of the temprecord a more unique name, eg: 2) append __LINE__ to ttemprecord的每个副本一个更唯一的名称,例如:

(See Creating C macro with ## and __LINE__ (token concatenation with positioning macro) ) (请参阅使用 ## 和 __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___);

Which would expand the code to this:这会将代码扩展为:

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

3) use the comma operator to define a nameless variable in the same expression that calls logmessage() , the variable will not go out of scope until logmessage() returns, eg: 3) 使用逗号运算符在调用logmessage()的同一表达式中定义一个无名变量,该变量不会 go 超出 scope 直到logmessage()返回,例如:

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

Which would expand the code to this:这会将代码扩展为:

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

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

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