Препроцессор C ++ __typeof - PullRequest
1 голос
/ 11 января 2012

Недавно я нашел и начал использовать в своем препроцессоре следующий код:

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

, что облегчает мою итерацию.Но, к сожалению, я не совсем понимаю вторую строку, особенно ключевое слово __typeof (и почему используются эти два подчеркивания).Я также предположил, что все выражение __typeof(b) является приведением типа, но когда я беру его в скобки, почему оно не работает?

Ответы [ 2 ]

3 голосов
/ 11 января 2012

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

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

2 голосов
/ 11 января 2012

Просто примите некоторые реальные значения для i и 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 и получите:

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

Как вы видите, часть __typeof является не типом, а декларацией, поэтому парантез там неправильный.

Также обратите внимание на множество комментариев о том, почему бы не использовать макросы и __typeof в специальных!

...