This brings up an interesting theoretical optimization feature of templates. If in the previous example the class Foo were a template, the size() method could just return a template parameter. Thanks to template semantics, calls to the size() method are subject to constant elimination, which may in turn lead to dead code elimination. That is an example of the compiler deciding on the course of some branches, and eliminating the actual branch instruction from the execution stream.
Similar code in C uses preprocessor macros to get the same benefits, and is not type-safe. Templates used this way save much space and execution time, and are more readable. Use templates as a means of manipulating the type structure of the program, and not a way to create code, and templates may actually reduce to take no code space at all.
If template methods are not inlined, the compiler must generate an implementation of the template, often in a different compilation unit. To make matters worse, much near-duplicate code may be generated. For example, instantiations with the ``int'' type and the ``unsigned'' type may generate identical code for a small inlined method but generate unique implementations for complex out-lined methods. Comparisons, for example, require different assembly code for ``int'' and ``unsigned'' values.
Templates are therefore a terrific way to generate lots of excess code when used in this fashion. When inlined, the compiler may use template semantics to implement efficient, locally optimized code. Otherwise, they generate lots of redundant code.
Compiler writers are still arguing over how to deal with template repositories and the like, but in practice, for our purposes, the issue is moot. Large template classes or functions will expand to consume all available ROM. Practical templates should be small enough to be inline, and if inlined everywhere, there is no need for a template repository.