Lesson 8 / 10

Templates and Generic Programming

A template lets you write one function or class that works with any type, without writing a separate version for each — the C++ equivalent of Java’s generics, and a feature that predates Java’s by several years.

template<typename T>nT max_of(T a, T b) {n    return (a > b) ? a : b;n}nnstd::cout << max_of(3, 7);        // works with intnstd::cout << max_of(2.5, 1.1);    // and with double, same function

Class templates

template<typename T>nclass Box {npublic:n    void set(T value) { contents = value; }n    T get() { return contents; }nprivate:n    T contents;n};nnBox<std::string> stringBox;nstringBox.set("C++");nBox<int> intBox;nintBox.set(42);

The compiler generates a specific, fully-typed version of the template for each type you actually use it with — this process is called template instantiation, and it’s why templates have zero runtime overhead compared to writing the type-specific code by hand yourself, unlike some generic mechanisms in other languages.

Templates you’ve already been using

std::vector<std::string> from the arrays lesson is itself a template — vector is a class template, and <std::string> is what instantiates it for that specific type. Recognizing this connects templates directly back to something you’ve already used successfully, rather than treating them as an entirely new, unfamiliar concept.

A word on error messages

Template-related compiler errors have a reputation for being long and intimidating, especially in older C++ standards. Modern compilers (with C++20 concepts, briefly) have improved this substantially. When you hit one, look for the first error in the message, near the bottom of the wall of text — that’s usually the actual root cause, with everything above it being consequences cascading from it.