template <class T>
class IntermittentQueue : Queue<T> { /* some other statements */ };
Это определяет новый класс шаблона:
template <class T>
class IntermittentQueue { }
, который в то же время наследуется от другого, например:
class Base { };
class Derived : Base { };
Исключительно, что в этом случае базовый класс является экземпляром другого шаблонного класса:
template <typename T>
class Base { };
class Derived : Base<int> { };
используя параметр шаблона производного класса в качестве аргумента шаблона (и теперь мы снова вернулись к исходному коду ...).
template <class T>
typename IntermittentQueue<T>::Node* IntermittentQueue<T>::getNode(const node_ptr nodePtr)
{ /* some other statements */ };
Это реализация одной из функций-членов класса шаблона. Шаг за шагом:
template <class T> // the class we are speaking off is a template class
typename IntermittentQueue<T>::Node* // return value of the function
IntermittentQueue<T>::getNode // function name with (template) class scope specified
// (just as with SomeClass::someMemberFunction)
(const node_ptr nodePtr) // function parameter(list)
{ /* some other statements */ }; // function body
Пока хорошо, но тип возвращаемого значения может нуждаться в дополнительном объяснении:
typename IntermittentQueue<T>::Node*
Функция возвращает указатель на объект типа внутреннего класса Node
из (шаблона) класса IntermittentQueue
:
IntermittentQueue<T>::Node*
Поскольку внутренний тип является зависимым типом, вам нужно , чтобы явно указать компилятору, что на самом деле является типом вообще, это то, что тогда используется ключевое слово typename
за; для деталей: уже есть еще вопрос к теме.
Здесь просто примечание: наличие typedefs для указателей (node_ptr
) - это плохая практика , это просто скрытие информации и ничего полезного для нее нет (исключение: указатель служит дескриптором к какому-либо внутреннему ресурсу и не предназначен для разыменования где-либо за пределами - тогда допустимо явное скрытие природы указателя).