Добавьте ключевое слово typename к этим строкам:
typedef std::vector<T>::const_iterator itType;
изменится на:
typedef typename std::vector<T>::const_iterator itType;
Ваш const_iterator является вложенным-зависимым-type - тип, вложенный в ваш тип параметра-типа, который зависит от него. Чтобы понять это различие, вы должны указать ключевое слово typename - сообщить компилятору, что это имя типа, основанного на вашем шаблоне.тип T.
Компиляторы часто не реализуют это достаточно корректно - некоторые позволяют вам обходиться без больше, чем другие.
Чтобы привести пример причины, по которой это необходимо, рассмотрим следующее:
T::X * var_name;
Компилятор может интерпретировать это как «Я хочу указатель на тип T :: X с именем var_name» или он может подумать «Я хочу умножить статическую переменную X в классе T на значение, хранящееся в var_name".
Добавление typename следующим образом:
typename T::X * var_name;
заставит его предпочесть первое, потому что теперь он знает, что T :: X является типом в этом контексте.