Почему ключевое слово «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 Я не понимаю, почему компилятор не спутал бы его сstatic int iterator ? - xcrypt

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

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

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

Ответы на вопрос(3)

Ваш ответ на вопрос