Хотя код может выглядеть как специализация шаблона, это не так.Язык не допускает частичной специализации шаблонных функций.Это несвязанные шаблоны, которые могут быть перегружены.
Компилятор выполнит поиск вызова fun( (Wrap<char>*&) i )
с обычными механизмами поиска, найдет два шаблона и определит, что существуют две потенциальные перегрузки:
template <typename T> void fun( T*& ); // with T == Wrap<char>
template <typename T> void fun( Wrap<T>*& ) // with T == char
Разрешение перегрузки определит, что второе лучше соответствует, и создаст его экземпляр.Это гарантируется стандартом, но будьте осторожны: это не один и тот же шаблон, а скорее разные шаблоны, и вы можете столкнуться с неожиданными результатами.Посмотрите на статью @LiKao, на которую есть ссылки, чтобы узнать больше.