2012-01-10 85 views
1

最近我發現,我已經用我的預處理下面的代碼開始:C++預處理器__typeof

#define FOREACH(i,s) for(VAR(i,(s).begin()); i != (s).end(); i++) 
#define VAR(a,b) __typeof(b) a=(b) 

是什麼讓我的迭代更加容易。但不幸的是,我不完全理解第二行,特別是關鍵字__typeof(以及爲什麼使用這兩個下劃線)。我還假定整個表達式__typeof(b)是一種類型轉換,但是當我將它放在括號中時,爲什麼它不起作用?

+8

」最近我找到了,我已經開始在我的預處理器中使用下面的代碼「現在應該是停下來的好時機。使用宏來混淆控制語句是一個非常糟糕的主意。 – 2012-01-10 20:37:55

+0

已經給出了很好的答案,我想補充一點,你現在不應該使用所有這些東西,用C++ 11,當你可以使用基於範圍的時候 - http://en.wikipedia.org/wiki/C%2B%2B11#基於範圍的循環 – Lol4t0 2012-01-10 20:44:42

+0

事實上,這個range_based-for(類似於Java)將解決這個問題。我知道對於其他人來說,這樣的代碼並不清晰,但它可以幫助我保持代碼更加透明(當然,只有在我自己使用程序時才使用這些宏) – JosephConrad 2012-01-10 21:03:32

回答

2

只是假設一些真正的價值爲我和s,看看它做什麼:

std::list<int> list; 
FOREACH(i, list) 

這將解決在宏觀FOREACH(i, list)

for(VAR(i, (list).begin()); i != (list).end(); i++) 

現在解決宏觀VAR(i, (list).begin())

__typeof((list).begin()) i = (list).begin(); 

其中__typeof獲得參數的類型(list).begin()這是在這種情況下std::list<int>::iterator

std::list<int>::iterator i = (list).begin(); 

現在插入該到了,並得到:

for(std:list<int>::iterator i = (list).begin(); i != (list).end(); i++) 

正如你所看到的__typeof部分是沒有類型轉換,但一個聲明,所以paranthesis是錯在那裏。

另請注意,爲什麼不在特殊情況下使用宏和__typeof有很多意見! 「

3

__typeof(b)不是演員。它是用G ++可用的非標準C++,意思是「b的類型」。換句話說,這是一種類型,並且__typeof(b) a=(b);是將a定義爲具有與b相同類型並且從b初始化的定義。所以在int b = 3;之後,這意味着int a = b;。標準C++ 11(這是相當新的並且尚未完全由我知道的任何編譯器實現)包括一個大部分相似的特性,稱爲decltype

+3

除此之外,'decltype'的幾乎所有用法都可以用'auto'取代(尤其是給定的)。至少從4.5開始,兩者都完全以g ++實現。 – filmor 2012-01-10 20:41:53

+0

哦,是的,我忘了這一點。謝謝。 – hvd 2012-01-10 20:46:03

+0

@filmor:僅當用作局部變量的類型說明符時。元編程中的decltype有很多用法,不能用auto來代替 – Grizzly 2012-01-10 23:02:06