簡體   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