Символ <
означает «меньше чем» и «начать аргументы шаблона». Чтобы различать эти два значения, парсер должен знать, называет ли предыдущий идентификатор шаблон или нет.
Например, рассмотрим код
template< class T >
void f( T &x ) {
x->variable < T::constant < 3 >;
}
Либо T::variable
, либо T::constant
должен быть шаблоном. Функция означает разные вещи, в зависимости от того, что есть, а что нет:
- либо
T::constant
сравнивается с 3, а логический результат становится аргументом шаблона для T::variable<>
- или
T::constant<3>
сравнивается с x->variable
.
Для устранения неоднозначности ключевое слово template
необходимо указывать перед variable
или constant
. Дело 1:
template< class T >
void f( T &x ) {
x->template variable < T::constant < 3 >;
}
Дело 2:
template< class T >
void f( T &x ) {
x->variable < T::template constant < 3 >;
}
Было бы неплохо, если бы ключевое слово требовалось только в реальных неоднозначных ситуациях (которые встречаются довольно редко), но это значительно облегчает написание синтаксического анализатора и предотвращает застревание таких проблем.
Стандарты см. В 14.2 / 4:
Когда имя члена шаблона
специализация появляется после. или ->
в постфиксном выражении или после
спецификатор вложенного имени в
квалифицированный идентификатор, а
Постфиксное выражение или уточненный идентификатор
явно зависит от
шаблон-параметр (14.6.2),
имя шаблона участника должно быть префиксом
по шаблону ключевого слова. В противном случае
имя предполагается, чтобы назвать
без шаблона.