2013-03-26 30 views
-4
#define EVENT_TYPE(DO) DO(EVENT_UNKNOWN), DO(EVENT_SIP), DO(EVENT_MEDIA), \ 
        DO(EVENT_APP), DO(EVENT_TIMER), DO(EVENT_BREAK), \ 
        DO(EVENT_STOP), DO(EVENT_MAX) 

如何理解這個關於在C++中定義的代碼示例?如何理解C++中有關define的代碼示例?

+2

通過查找傳遞給它('DO')和相關的參數。如果沒有這個,我們怎麼可能告訴你它做了什麼? – 2013-03-26 03:10:05

回答

2

宏是簡單的替換。因此,無論您將EVENT_TYPE的arg get放在哪裏,您都會在右側的事件列表中看到「DO」。例如,EVENT_TYPE(GUI)將被替換成:

GUI(EVENT_UNKNOWN), GUI(EVENT_SIP), GUI(EVENT_MEDIA), \ 
GUI(EVENT_APP), GUI(EVENT_TIMER), GUI(EVENT_BREAK), \ 
GUI(EVENT_STOP), GUI(EVENT_MAX) 

這是可能的,這是爲了與其它宏,以便使用GUI(或無論是在那裏)本身將是會做這樣的事情,比如說宏,預先安排一個名稱空間(因此第一個元素變爲MyNamespace :: MyUI :: EVENT_UNKNOWN)或連接標識符字符串(因此第一個元素變爲GUI_EVENT_UNKNOWN)。

更新: 從您的評論:

#define STRINGIFY(VAR) #VAR 

使得串出不管你把變種。通常這將是一個變量名稱,但它可能是一個表達式。因此,預處理器將改變:

int i = 42; 
std::cout << STRINGIFY(i) << " = " << i << '\n' 
      << STRINGIFY(i+1) << " = " << i+1 << '\n'; 

int i = 42; 
std::cout << "i" << " = " << i << '\n' 
      << "i+1" << " = " << i+1 << '\n'; 

,它將打印:

i = 42 
i+1 = 43 

你也可以做符號拼接:

#define CONCAT(X) prefix_##X##_suffix 

int CONCAT(myVar) = 42; 

將變爲:

int prefix_myVar_suffix = 42; 

你也可以做字符串連接,但我會把它作爲讀者的練習。

+0

#define MAKE_STRINGS(VAR)#VAR? – jiafu 2013-03-26 03:30:38

+0

發佈了更新。 – metal 2013-03-26 12:22:12

1

它會替代DO以代替DO,如函數或仿函數。生成的代碼會調用你所代替的函子的代替DO的功能,並將其作爲EVENT_UNKNOWN的每一個,並將它們返回,就像放置它們a,b,c一樣。

您可以使用它來創建一組事件的枚舉。例如:

// create array of all of EVENT_UKNOWN... as integers 
int array[] = { EVENT_TYPE((int)) }; 

// Create array of strings 
class Foo { 
public: 
    std::string operator()(int val) { ... } 
}; 

Foo f; 
std::string strings[] = { EVENT_TYPE(f); } 
+0

謝謝,關於#define MAKE_STRINGS(VAR)#VAR – jiafu 2013-03-26 03:30:55

+0

#宏擴展中的#被稱爲字符串化,或用精確的字符串文字替換。因此,EVENT_TYPE(MAKE_STRINGS)將返回每個「EVENT_UNKNOWN」的逗號分隔字符串列表,... – 2013-03-26 17:53:24