При синтаксическом анализе типа возврата (как определено в вопросе) мы пока не находимся в области действия Queue<T>
. Ваши рассуждения были бы правильными, если бы вы написали
template<typename T>
auto Queue<T>::test() -> Node* {
}
Вложенный префикс имени полного имени функции ставит нас в рамки текущей специализации шаблона. Здесь поиск безусловного имени находит Node*
в текущей специализации, где известно, что он ссылается на тип.
Но при синтаксическом анализе возвращаемого типа в вашем вопросе компилятор еще не столкнулся с «текущей специализацией» где Node*
можно однозначно предположить, чтобы назвать тип. Все, что он видит, - это мы пишем зависимое имя из некоторой специализации. Таким образом, typename
требуется. Для нас нет ничего необычного в том, чтобы писать
template<typename T>
typename OtherUnrelatedClass<T>::Node* Queue<T>::test() {
}