Designing Generic Code
intermediate20 min readLesson 115 of 204
Concrete-first workflow, naming the contract, testing with unrelated types, and when not to template.
Writing your own templates is a design activity. The discipline:
- Write the concrete version first. Make it work for one type.
- Generalize mechanically. Replace the concrete type with T and move type-specific operations behind the contract.
- Name the contract in comments or concepts.
T must be movable and support operator<is the interface your callers read. - Test with at least two unrelated types — int and std::string is the classic pair; if your template only compiles for one, it is not generic yet.
// step 1-3 applied: a generic clamp
template <typename T>
T clamp_to(const T& v, const T& lo, const T& hi) {
// contract: T supports operator< (and copies cheaply or is passed by ref)
if (v < lo) return lo;
if (hi < v) return hi;
return v;
}
When not to template: runtime-varying behavior (that is polymorphism), a single concrete call site (premature), or an API boundary where the type must be named for documentation. Templates trade error-message clarity for code reuse — charge that cost only when reuse is real.