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