- The need for compile-time polymorphism vs. runtime polymorphism.
- The desire for generalization and flexibility.
For 1, you generally don't have a choice -- compile time polymorphism is either what you want, or not what you want. Its the solution to your problem, or it isn't. It presents a different set of compositional properties than run-time polymorphism. Knowing the difference will shed a great deal of light on the value of templates and generic programming in general.
For 2, the choice is often subjective -- is it less work to be generic now, or to duplicate some code in some cases? Which is easier for your team to understand? How far is your compiler willing to support your templating efforts (ie, does it support partial template specialization or not)? In general, I would agree that your observation in this light is largely correct: It's "factually" better to be generic, but in practice most code isn't re-used. You just need to be able to judge which code falls into which camp. Containers and algorithms are great candidates for example (such as in the C++ standard library) but it probably doesn't make much sense to templatize classes that represent logic (in the sense of decision-making, interaction and control, more than formal algorithms).