Важно понимать, что такое шаблоны: это код, который заново создается для каждой комбинации определенных типов шаблонов или значений.
void f(const int j) { CAT<j> cat; }
Это просит f
создавать новый тип CAT<>
при каждом запуске, но шаблоны должны быть разрешены во время компиляции. Концептуально, компилятор мог бы справиться, если бы вы только когда-либо вызывали f()
со значениями, с которыми он мог бы работать во время компиляции, но если вы планируете это сделать, вы можете просто написать:
template <int N>
void f() { CAT<N> cat; }
Эта будет генерировать несколько f()
функций, которые создают пользовательские CAT <> экземпляры.
Стандарт C ++ даже не требует, чтобы компилятор предварительно принял версию void f(const int j)
- это был бы просто сомнительный багаж, зависший в ожидании сбоя, когда кто-то использовал его со значением, определенным во время выполнения. Люди, которые смотрят на интерфейс, не просматривая всю реализацию, ожидают, что f()
будет вызываться с такими значениями времени выполнения - например, f(atoi(argv[2]))
. Или они могут поставить for (int i = 0; i < 100000; ++i) f(i)
. Если f()
принимает int
во время выполнения и, скажем, передает его CAT
в качестве аргумента конструктора (то есть в качестве параметра времени выполнения, а не параметра шаблона), то это нормально, но если компилятор пришлось создать 100 000 версий f()
, каждая из которых специализировалась на CAT<>
с последовательными значениями i/N
, размер исполняемой программы мог бы стать огромным (оптимизация - если она включена - может уменьшить это).