Здесь вам вообще не нужна специализация: iterator_traits
уже специализирован для типов указателей, и если у вас получится итератор, являющийся типом класса, вы можете просто определить требуемые typedef
s в класс итератора.
Проблема в том, что для соответствия первичной специализации компилятору необходимо взять аргументы, с которыми используется шаблон, подключить их к специализации и посмотреть, совпадают ли они.
Рассмотрим, что произойдет в следующем упрощенном сценарии:
template <typename T> struct S { typedef int type; };
template <typename T>
struct Traits { };
template <typename T>
struct Traits<typename S<T>::type> { };
Как компилятор должен знать, что T
подключить к S
или действительно ли подразумевается какой-то S<T>::type
вместо int
?
Проблема в том, что вложенный typedef (::type
) зависит от параметра шаблона (T
). Когда это имеет место в списке аргументов функции или в частичной специализации, тип T
не может быть выведен (это «не выводимый контекст»).