2012-01-10 3 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

«Недавно я нашел, и я начал использовать в своем препроцессоре следующий код:« Теперь самое подходящее время для остановки. Обфускация управляющих операторов с использованием макросов - очень плохая идея. –

+0

Хорошие ответы были даны, я бы хотел добавить, что вы не должны использовать все это сейчас, с помощью C++ 11, когда вы можете использовать диапазон на основе http://en.wikipedia.org/wiki/C% 2B% 2B11 # Range-based_for-loop – Lol4t0

+0

Действительно, этот range_based-for (аналогичный Java) решит проблему. Я знаю, что для других такой код не ясен, но он помогает мне сохранить мой код более прозрачным (конечно, я использую такие макросы только при написании программ для собственного использования) – JosephConrad

ответ

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) не является литой. Это нестандартный C++, который можно использовать с G ++, и означает «тип b». Другими словами, это тип, а __typeof(b) a=(b); - это определение, которое определяет a как имеющий тот же тип, что и b, и инициализируется от b. Итак, после int b = 3;, это означает int a = b;.

Стандарт C++ 11 (который довольно новый и еще не полностью реализован любым компилятором, который я знаю) включает в основном аналогичную функцию, называемую decltype.

+3

И кроме этого почти любое использование 'decltype' может быть заменено на' auto' (особенно на тот, который указан). Оба они полностью реализованы в g ++ по крайней мере с 4.5. – filmor

+0

О да, я забыл об этом. Благодарю. – hvd

+0

@filmor: только при использовании в качестве спецификатора типа для локальных переменных. В метапрограммировании есть много применений для decltype, которые нельзя заменить авто – Grizzly

Смежные вопросы