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 разных типов, что неприемлемо ».