"явно создать экземпляр"
Это означает сообщить компилятору о создании функции из шаблона функции с некоторыми указанными типами, даже если это может не потребоваться (например, чтобы иметь возможность ссылаться на нее илисократить время компиляции).
Шаблон можно рассматривать как «функцию уровня типа».Ваш to_hex
принимает некоторый тип в качестве аргумента и «возвращает» функцию некоторого типа.
to_hex :: T -> to_hex<T>
Ваш fixed_buf
также является функцией уровня типа.Он принимает некоторое целое число (уровень типа времени компиляции) и возвращает (структурный) тип:
fixed_buf :: int(N) -> fixed_buf<N>
Вы не можете "передать" fixed_buf
в to_hex
;это не тип, а функция уровня типа.Вы можете передать только результат fixed_buf
.Если вы не знаете, какое целое число (уровня типа) передать в fixed_buf
, вам необходимо превратить это в функцию (уровня типа):
\N -》 to_hex(fixed_buf(N)) :: int(N) -> to_hex<fixed_buf<N>>
Без определенного целого числа уровня типа это не тип, хотя;и компилятором могут быть созданы только типы (= полностью примененные шаблоны в этом случае).
Таким образом, вы можете явно создать экземпляр to_hex<fixed_buf<42>>
(это одна функция), но не to_hex<fixed_buf<N>>
(шаблон).
Вы можете явно создать экземпляр to_hex<fixed_buf<1>>
, to_hex<fixed_buf<2>>
, ... хотя;но я не думаю, что было бы разумно сделать это
Если вы не имеете в виду создание экземпляра, а скорее "специализацию", то опять нет, вы не можете предоставить специализацию шаблона, потому что это потребуетбыть частичной специализацией (вы не знаете N
), и это не разрешено для функций.Решения:
поместить реализацию в шаблон struct
;они могут быть частично специализированными.
Использовать перегрузку:
template <int N>
string to_hex(const fixed_buf<N>& b) { /* implementation */ }
Это перегрузка (не частичная специализация; они не разрешены для шаблонов функций), которыедолжно работать.