Skip to main content

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:

  1. Write the concrete version first. Make it work for one type.
  2. Generalize mechanically. Replace the concrete type with T and move type-specific operations behind the contract.
  3. Name the contract in comments or concepts. T must be movable and support operator< is the interface your callers read.
  4. 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.