devnotes.

Function and Class Templates

Templates let you write a function or class once, generically, and have the compiler generate a specific version for whatever type is actually used — C++'s mechanism for generic programming.

template <typename T>
T maxVal(T a, T b) {
    return (a > b) ? a : b;
}

maxVal(3, 7);          // compiler generates an int version -> 7
maxVal(3.5, 2.1);       // compiler generates a double version -> 3.5
maxVal("abc", "xyz");   // works for any type supporting >

template <typename T>
class Box {
private:
    T value;
public:
    Box(T v) : value(v) {}
    T get() const { return value; }
};

Box<int> intBox(42);
Box<std::string> strBox("hello");

template <typename T> (or the equivalent template <class T>) declares T as a placeholder type, filled in with a concrete type each time the template is actually used — this process is called instantiation, and it happens at compile time: the compiler generates a separate, fully-typed version of maxVal for int, another for double, and so on, rather than the single runtime-checked version generics use in languages like Java.

Because instantiation happens per-type at compile time, templates carry no runtime overhead compared to writing each type-specific version by hand — this is why the entire STL, including every container and algorithm, is built on templates: std::vector<int> and std::vector<std::string> are genuinely two different compiler-generated classes, not one class working with a generic Object type.

Template errors can look intimidating (long, deeply-nested error messages) because they surface only once a template is instantiated with a specific type that turns out not to support some required operation — this is a common early frustration, but the underlying cause is almost always straightforward once you find the actual line that failed inside the wall of text.

Function and Class Templates in C++ | DevNotes