Вы можете сделать что-то вроде того, что сказал Матье, выписывать отдельные функции для каждого типа вы поддерживаете (его могут по-прежнему вызывать функцию шаблона в бэкэнд) или использовать динамический полиморфизм и наследование. Это должны быть только те варианты, которые вы должны учитывать, чтобы делать то, что хотите.
Однако вопрос, который вы задаете, заставляет меня поверить, что это неправильное понимание шаблонов и статического полиморфизма. Шаблон функции/класса налагает ограничение на типы, с которыми он может работать, посредством генерируемого фактического кода. Открытый интерфейс, который используется в таких функциях/классах, определяет ограничения на типы, которые могут быть приняты. Нет необходимости излишне налагать дополнительные ограничения на это. Почему вы хотите ограничить типы, которые шаблон типа/функции может поддерживать больше, чем уже установленные ограничения?
Предположим, вы пишете шаблон функции, который может работать только с типами, реализующими открытый интерфейс, который состоит из объекта доступа к жизни, функции уничтожения и функции питания (в основном, любого живого организма). Это ограничение, которое оно накладывает: вам не нужно ограничивать гибкость, уменьшая количество типов, которые будут работать с шаблоном функции, выходящим за рамки этого, или определите какие-либо конкретные типы организмов, которые будут работать таким образом. Шаблон уже требует, чтобы этот интерфейс живого организма был реализован.