Этот эффект не связан напрямую с псевдонимом типа через using
, это результат поиска имени для члена текущей реализации.
Внутри BST
оба выражения BST
и BST<ElementType>
относятся к текущему экземпляру, и его члены можно найти без использования префикса typename
, который вы можете сделать:
template <typename ElementType>
void BST<ElementType>::some_func() {
BST::NodePtr ptr; // or
BST<ElementType>::LinkNode * ptr2;
}
в результате чего то же самое.Но теперь давайте предположим, что some_func
также является функцией-членом шаблона, определенной как:
template <typename ElementType>
struct BST {
class LinkNode { /*...*/ };
using NodePtr = LinkNode *;
template <typename T>
void some_func();
};
template <typename ElementType>
template <typename T>
void BST<ElementType>::some_func() {
BST<T>::NodePtr ptr; // (1)
BST<T>::LinkNode * ptr2 // (2)
}
Теперь ни (1), ни (2) не будут компилироваться, потому что B<T>
больше не является текущей реализацией, следовательно, вв этих случаях вам нужно typename
.
Соответствующая часть стандарта [temp.res]/7
:
В пределах определения шаблона класса или в определении члена классаВ шаблоне, следующем за идентификатором объявления, ключевое слово typename не требуется при обращении к имени ранее объявленного члена шаблона класса, который объявляет тип или шаблон класса.[...]