Module 12 — Summary¶
The essentials¶
- A template is a pattern, not a type. The compiler generates a concrete function or class for
each set of arguments it is used with, at compile time, with no run-time cost — which is also why
it works for
int, and why it cannot grow after the program is compiled. - Templates are checked twice: syntax and non-dependent names when the definition is read,
everything involving
Tat instantiation. That is why errors arrive late, and why "it compiles" means very little until it is instantiated for the types you intend to use. - The definition must be visible where the type is used, so template code normally lives in a
header. The alternative — a
.cppplus explicit instantiations — trades flexibility for build time, and makes each new type a deliberate decision. - Every template imposes requirements, whether or not anybody wrote them down. The error for a type that fails is the requirement surfacing, and it is always about your type.
- Document the requirements, and enforce what can be enforced. A
static_assertwith a message turns a page of diagnostics into one line that names the requirement and the alternative. typenameis required for a dependent type name (typename T::value_type), because untilTis known the compiler cannot tell a type from a static value.- Non-type parameters make a value part of the type. A capacity known at compile time gives storage inside the object, checks at compile time, and an error the moment the value comes from configuration instead.
- Specialise for correctness, not for convenience.
Formatter<bool>fixes a real defect; the standard library'sstd::vector<bool>trades addressability for memory and is still argued about.if constexprbranches inside one implementation, and the branch not taken is discarded. - Compile-time and run-time polymorphism trade differently. Templates avoid dispatch and extend only by recompiling; virtual interfaces dispatch and can be extended by code written later. The question is whether the type is a fact about the design or something the program discovers.
- Read a template error from the end, find the frame naming your own file, then reduce it to five lines. In generic code, reduction is not a debugging step — it is the method.
- Generalise when the second genuine use appears, not in anticipation. Two callers are evidence; "we might need it" is a cost with no benefit.
The one-sentence version¶
Write the code once in terms of a type you do not know yet, state what that type must provide, and let the compiler generate — and check — a real version for every type that actually gets used.
Terms you must now be able to define¶
template · function template · class template · template parameter · type
parameter · non-type parameter · deduction · instantiation · explicit
instantiation · dependent name · typename · requirement · static_assert ·
type trait · if constexpr · full specialisation · partial specialisation ·
class template argument deduction · code bloat · generic programming
All of them are defined in the glossary under this module.
Before you move on¶
- [ ] All core exercises attempted, with the results checked
- [ ] The lab builds with no warnings and passes its checklist
- [ ] The requirement failure was forced on purpose, captured, and reduced to five lines
- [ ] The repository was instantiated for two unrelated types
- [ ] Quiz score ≥ 80%, and every miss explained
- [ ] At least one challenge problem attempted — including the argument against generalising
- [ ] Skills checklist ticked, with the evidence for each item
- [ ] I can read a template diagnostic and find the sentence that is about my type
Where this goes next¶
Module 13 — Exception Handling is the next thing your
generic components need. A Repository<T> part-way through an operation that throws must be left in
a known state, and that is what exception-safety guarantees are for; the code that satisfies them is
built from Module 11's ownership and this module's genericity. Lab 11 previewed throw as a
mechanism; Module 13 makes failure a designed part of the system.
Module 14 — The STL with OOP is this module applied. Every container and algorithm there is a template, every one of them states its requirements, and the errors you will meet are exactly the ones this module taught you to read. If the last line of a diagnostic still looks like noise, Module 14 will feel like a list of names; if it reads as a sentence about your type, Module 14 is where the rest of the standard library becomes usable.
Further reading¶
- Effective Modern C++, Scott Meyers — practical template reasoning, deduction, and why some template code is best avoided.
- The C++ Programming Language (4th ed.), Bjarne Stroustrup — templates in depth, and the argument for why they are the basis of the standard library.
- cppreference: templates — the language reference, including the exact rules for deduction and the requirement lists of every standard algorithm.
- Modern C++ Design, Andrei Alexandrescu — only if you want to go well beyond this module; it
assumes the material here is already comfortable, and it is the source of the techniques that
produced
std::functionandstd::tuple.
See Further Reading for the full list, with what each source is good for and when to reach for it.