На этом шаге мы рассмотрим использование ключевого слова typename.
Ключевое слово typename означает, что следующий за ним идентификатор обозначает тип. Рассмотрим следующий пример:
template <class T> class MyClass { typename T::SubType * ptr; . . . };
В этом фрагменте ключевое слово typename поясняет, что SubType является подтипом класса Т. Следовательно, ptr - указатель на тип T::SubType. Без typename идентификатор SubType интерпретируется как статический член класса, а следующая строка воспринимается как умножение значения SubType типа Т на ptr:
Т::SubType * ptr
Поскольку идентификатор SubType объявлен типом, любой тип, используемый вместо Т, должен содержать внутренний тип SubType. Например, использование типа Q в качестве аргумента шаблона, как показано ниже, возможно только при условии, что в Q определяется внутренний тип SubType:
MyClass<Q> x;
Объявление выглядит примерно так:
class Q { typedef int SubType; . . . };
В этом случае переменная ptr класса MyClass<Q> является указателем на тип int. Однако подтип также может быть абстрактным типом данных (например, классом):
class Q { class SubType: . . . };
Ключевое слово typename всегда должно квалифицировать идентификатор шаблона как тип, даже если другая интерпретация не имеет смысла. В C++ любой идентификатор шаблона, указанный без ключевого слова typename, интерпретируется как значение.
Ключевое слово typename также может использоваться вместо слова class в объявлении шаблона:
template <typename T> class MyClass;
На следующем шаге мы рассмотрим шаблонные функции классов.