5.2.14 · D1C++ Programming

Foundations — Templates — function templates, class templates

1,891 words9 min readBack to topic

This foundations page assumes nothing. Every squiggle, keyword, and angle bracket the parent note throws at you is built here from the ground up, in an order where each piece leans only on the pieces before it.


0. What is a "type"? (the blank we will parameterize)

Before we can make the type a parameter, you must be crystal clear on what a type is.

The picture: think of a value as an object living in a labelled box. The label is the type. The same pattern of bits means different things under different labels — that is exactly why the label matters.

Why the topic needs this: templates exist precisely because the same algorithm (return a > b ? a : b) works for many different labels. Once you see that int, double, and string are just interchangeable labels on the same shape of logic, the desire to "leave the label blank" becomes obvious. See Compile-time vs Runtime for when the label is decided.


1. The function — a named recipe with typed slots

int maximum(int a, int b) { return (a > b) ? a : b; }
//  ^ret    ^name ^param1  ^param2   ^body
  • int before the name = the return type (the label on the answer box).
  • a, b = parameters, each with a type int.
  • (a > b) ? a : b = the ternary operator: read it as "if a > b is true, give a, otherwise give b". It is just a compact if/else that produces a value.

The picture: a machine with two labelled input trays and one labelled output tray. Same machine works for whatever you feed it — as long as the trays accept that type.

Why the topic needs this: the parent starts from exactly this concrete maximum. A template is born by pointing at every int here and asking "what if this were a blank?" If you need a refresher on writing one recipe for several types manually, that is Function Overloading — templates replace it.


2. The operators the body silently relies on: > and copy

The body uses two operations and only two:

  1. > — the greater-than comparison. Returns true or false.
  2. Copyreturn a hands back a copy of the value.

Why the topic needs this: understanding that a template quietly demands certain operations is the difference between "templates are magic" and "templates are a substitution then a compile". This idea is the seed of Generic Programming.


3. <> — the angle brackets that carry parameters

You have seen () carry value arguments: maximum(3, 7). Templates introduce a second kind of bracket.

Bracket Carries Decided when
( ) values (data) at runtime
< > types / compile-time numbers at compile time

The picture: two conveyor belts feeding the same machine. The () belt drops in values; the <> belt drops in type-labels and is emptied first, at build time.

Why the topic needs this: vector<int>, Box<string>, Array<double, 5> — every one of those <...> is the compile-time belt in action. Understanding this split is what Compile-time vs Runtime is all about.


4. T — a name that stands for a type

Think of T like the x in f(x) = x + 1. x is not a number — it is a stand-in you replace with a real number when you actually use f. Likewise T is replaced with a real type (int, string) when you actually use the template.

Why the topic needs this: T is the single most-used symbol on the whole parent page. Every T maximum(T a, T b) reads "a function whose return, first param, and second param all share one type, called T".


5. template<typename T> — the header that declares the blank

Now we assemble the pieces:

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

Read the first line as three separate words:

  • template — the keyword announcing "what follows is a blueprint, not final code".
  • <typename T> — "it has one blank; the blank is a type, and I will call it T".
  • typename — literally "the name of a type". You may also write class Tidentical meaning for a type parameter (a historical quirk, covered in Macros vs Templates and the parent's steel-man).

The picture: a rubber stamp. The template<...> head is the handle and empty die; the function below is the engraving with a hole where T sits. Press it onto int and the hole fills with int.

Why the topic needs this: this exact header opens every function template and class template on the parent page. If you can read this line aloud in plain words, the rest of the note follows.


6. Instantiation — the stamp actually pressing

Key consequence (stated on the parent): an unused template produces zero machine code. The stamp makes an imprint only when you press it. This is why templates have zero runtime overhead — the stamped code is exactly what you'd have hand-written.

Why the topic needs this: "instantiation" is the verb that turns a blueprint into a working part; the whole payoff of templates lives here.


7. Specialization — a hand-carved override for one type

Example from the parent: printing a bool. The generic cout << b prints 1/0; the specialization prints true/false. The compiler always prefers the most specific matching version. Full treatment lives in Template Specialization.

The picture: you own a star cookie-cutter (the generic template). For one special order you set the cutter aside and hand-sculpt a different star (the specialization). Everyone else still gets the machine-stamped star.

Why the topic needs this: it answers "what if one-size-fits-all doesn't fit?" — a question the reader will absolutely hit.


The prerequisite map

Type = label on a value

Function = typed recipe

Operators T must support

Angle brackets carry types

T = a type placeholder

template of typename T header

Instantiation stamps real code

Specialization overrides one type

TEMPLATES topic

Each box uses only the boxes feeding into it — read top to bottom and nothing is used before it is built.


Equipment checklist

Cover the right side and test yourself. If any answer is fuzzy, re-read that section before opening the parent note.

What does a type tell the computer?
How many bytes a value takes and which operations are legal on it.
In int maximum(int a, int b), name the return type and the parameters.
Return type int; parameters a and b, both of type int.
What does the ternary (a > b) ? a : b mean in plain words?
If a > b is true, give a, otherwise give b.
Which two operations does maximum's body secretly require of any type?
> (greater-than) and the ability to copy the value.
What do ( ) carry, and when are they decided?
Values (data), decided at runtime.
What do < > carry, and when are they decided?
Types (or compile-time numbers), decided at compile time.
Is T a type?
No — it is a placeholder name for a type that gets supplied later.
Read template<typename T> aloud in plain words.
"This is a blueprint with one type-blank, which I'll call T."
Is template<class T> different from template<typename T>?
No — identical for a type parameter.
What is instantiation?
The compiler filling the blank and generating real code for one specific type.
How much machine code does an unused template produce?
None — code is generated only when the template is actually used.
What does template<> (empty brackets) introduce?
A full specialization — a separate hand-built version for one specific type.