class A
{
static int iterator;
class iterator
{
[...]
};
[...]
};
Я (думаю, я) понимаю причину typename
здесь:
template <class T>
void foo() {
typename T::iterator* iter;
[...]
}
но я не понимаю, почему typename
здесь не нужен:
void foo() {
A::iterator* iter;
[...]
}
Может ли кто-нибудь объяснить?
EDIT:
Причина, по которой у компилятора нет проблемы с последним, я нашел ответ в комментариях:
в случае A::iterator
Я не понимаю, почему компилятор не путал бы его с static int iterator
? - xcrypt
@xcrypt, потому что он знает, что оба A::iterator
есть и могут выбрать, какой из них зависит от того, как он используется - Seth Carnegie
Причина, по которой компилятор нуждается в typename
перед квалифицированными зависимыми именами, на мой взгляд, очень хорошо ответил на принятый ответ Kerrek SB. Не забудьте также прочитать комментарии к этому ответу, особенно этому iammilind:
"T:: A * x; это выражение может быть истинным для обоих случаев, где T:: A - тип, а T:: A - значение. Если A - тип, то это приведет к объявлению указателя, если A - значение, то это приведет к умножению. Таким образом, один шаблон будет иметь разное значение для двух разных типов, что неприемлемо."