Компилятор часто может выводить аргументы шаблона в явной реализации шаблона, что и есть.
См. [Temp.explicit] ( exmphasis mine )
Если явное создание экземпляра для функции или функции-члена,
unqualified-id в объявлении должно быть либо template-id , либо , где все аргументы шаблона могут быть выведены ,
имя-шаблона или идентификатор-функции-оператора .
Стандарт обеспечивает этот сопровождающий пример:
template void sort(Array<char>&); // argument is deduced here
В вашем примере объявление функции (которое также является определением) выглядит так:
template <typename IO>
bool flif_decode(IO& io, /*etc*/) { /*...*/}
Итак, когда мы позже увидим явный экземпляр, подобный этому:
template bool flif_decode(FileIO& io, /*etc*/);
Компилятор может определить, что FileIO
- это тип, который вы хотите использовать для typename IO