Почему ключевое слово «typename» необходимо перед квалифицированными зависимыми именами, а не перед квалифицированными независимыми именами?

class A
{
   static int iterator;
   class iterator
   {
      [...]
   };
   [...]
};

Я (думаю, что) понимаю причину, по которой здесь требуется typename :

template <class T>
void foo() {
   typename T::iterator* iter;
   [...]
}

, но я не понимаю, почему здесь не требуется typename :

void foo() {
   A::iterator* iter;
   [...]
}

Может ли кто-нибудь объяснить?


РЕДАКТИРОВАТЬ:

Причину, по которой компилятор не имеет проблем с последним, я нашел хорошо ответ в комментарии:

в случае A :: iterator Я не понимаю, почему компилятор не перепутал его со статическим итератором int ? - xcrypt

@xcrypt, потому что он знает, что такое оба A :: iterator , и может выбрать, какой из них, в зависимости от того, как он используется - Сет Карнеги


Причина, по которой компилятору требуется typename перед квалифицированными зависимыми именами, на мой взгляд, очень хорошо ответил в принятом ответе Керрека С.Б. Не забудьте также прочитать комментарии к этому ответу, особенно этот от iammilind:

«T :: A * x;», это выражение может быть истинным для обоих случаев, когда T :: A является типом, а T :: A является значением. Если A является типом, тогда это приведет к объявлению указателя; если A является значением, тогда это приведет к умножению. Таким образом, один шаблон будет иметь разное значение для 2 разных типов, что неприемлемо ».

17
задан xcrypt 15 January 2012 в 00:10
поделиться