[1] Use templates to express algorithms that apply to many argument types;
[2] Use templates to express containers;
[3] Provide specializations for containers of pointers to minimize code size;
[4] Always declare the general form of a template before specializations;
[5] Declare a specialization before its use;
[6] Minimize a template definition’s dependence on its instantiation contexts;
[7] Define every specialization you declare;
[8] Consider if a template needs specializations for C-style strings and arrays;
[9] Parameterize with a policy object;
[10] Use specialization and overloading to provide a single interface to implementations of the same concept for different types;
[11] Provide a simple interface for simple cases and use overloading and default arguments to express less common cases;
[12] Debug concrete examples before generalizing to a template;
[13] Remember to e x p o r t template definitions that need to be accessible from other translation units;
[14] Separately compile large templates and templates with nontrivial context dependencies;
[15] Use templates to express conversions but define those conversions very carefully;
[16] Where necessary, constrain template arguments using a constraint() member function;
[17] Use explicit instantiation to minimize compile time and link time;
[18] Prefer a template over derived classes when runtime efficiency is at a premium;
[19] Prefer derived classes over a template if adding new variants without recompilation is important;
[20] Prefer a template over derived classes when no common base can be defined;
[21] Prefer a template over derived classes when built-in types and structures with compatibility constraints are important;