Templates
By the end of this lesson you'll be able to write one piece of code that works with any type — function templates, class templates, multiple type parameters, defaults, and a first taste of specialization — the exact technique the entire C++ Standard Library is built on.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
A template is a cookie cutter . The cutter defines the shape ; the dough is the type . Press it into sugar dough and you get a sugar cookie; press it into gingerbread and you get a gingerbread cookie — same shape, different material. You write the shape once ( template typename T ) and the compiler stamps out a concrete version for every type you actually use. You don't get an int version until you press the cutter into an int .
1. Function Templates & Type Deduction
Without templates you'd copy maxOf once per type: one for int , one for double , one for string . A function template replaces all of them with a single recipe. You write template typename T above the function, then use T wherever a type would go. T is a placeholder : the compiler stamps out a real version the moment you call it. And thanks to type deduction , you usually don't even name the type — the compiler reads your arguments and works T out for itself.
Your turn. The program below is almost complete — write the template typename T line and the comparison so minOf returns the smaller value. Fill in the two blanks marked ___ using the hints, then run it.
2. Class Templates, Multiple Params & Defaults
Templates aren't just for functions — a class template makes a whole class generic. Box T can hold an int , a string , or anything else. You can declare multiple type parameters too: Pair K, V has two independent placeholders. And a default template argument ( typename V = int ) lets callers leave a parameter off and get a sensible default — just like a default function argument. One gotcha: class templates need the type written in ... when you create an object; deduction only happens automatically for function templates.
Now you try. Creating an object from a class template means putting the type inside the angle brackets. Fill in the two blanks so price is a Box of double and name is a Box of string :
3. Specialization & Where Errors Appear
Sometimes the general template is wrong for one specific type. Template specialization lets you hand-write a dedicated version for exactly that type, using template . The classic case is comparing C-strings: the general compares pointer addresses , not the text, so you specialize to compare the real characters. This section also shows the single most confusing thing about templates: errors appear at instantiation , not at definition. A template you never call is never type-checked — the compiler only complains when you actually use it with a type that doesn't fit.
You'll see both template typename T and template class T in real code. For declaring a type parameter they mean exactly the same thing . Modern code prefers typename because the placeholder doesn't have to be a class — it can be int , double , a pointer, anything.
No blanks this time — just a brief and an outline. Write a function template clamp that pins a value between a low and high bound, then prove it's generic by calling it with both int s and double s. Check your output against the example in the comments.
Practice quiz
Which line correctly declares a function template with one type parameter T?
- template typename T
- template <typename T>
- typename <template T>
- template T<typename>
Answer: template <typename T>. template <typename T> introduces T, a placeholder for any type, before the function or class.
In the call maxOf(10, 20) with template <typename T> T maxOf(T, T), what type is T deduced as?
- double
- int
- long
- It must be stated explicitly
Answer: int. Both arguments are int literals, so template type deduction makes T = int. No explicit <int> is needed.
What does template <typename V = int> add to a class template?
- A default template argument for V
- A forced specialization
- A runtime default value
- A second base class
Answer: A default template argument for V. = int is a default template argument: if the caller omits V, it becomes int, just like a default function argument.
Is there any difference between template <typename T> and template <class T> for declaring a type parameter?
- typename allows non-class types only
- class allows non-class types only
- No difference at all
- class is faster to compile
Answer: No difference at all. For declaring a type parameter they are identical. typename is preferred because the placeholder need not be a class.
When is a function template actually type-checked for a given type?
- At its definition
- When it is instantiated (used) with that type
- Only at link time
- Never
Answer: When it is instantiated (used) with that type. A template is only checked when instantiated, which is why errors appear at the call site, not the definition.
Creating an object from a class template Box<T> requires what?
- Nothing — the type is always deduced
- The type written in angle brackets, e.g. Box<int>
- A specialization first
- A virtual destructor
Answer: The type written in angle brackets, e.g. Box<int>. Before C++17 CTAD, class templates need the type spelled out, e.g. Box<int> b(42). Function templates deduce; classes (here) do not.
Why specialize maxOf for const char* (C-strings)?
- To make it run faster
- Because the general > compares pointer addresses, not the text
- Because const char* has no operator>
- To avoid a linker error
Answer: Because the general > compares pointer addresses, not the text. For const char*, the general > compares pointer addresses. The specialization compares the actual characters instead.
What syntax begins a full template specialization?
- template <T>
- specialize <T>
- template <>
- template default <>
Answer: template <>. template <> introduces a full specialization — a hand-written version for one specific type.
Why must template definitions usually live in header files?
- Headers compile faster
- The compiler needs the full body visible where the template is used
- Templates cannot appear in .cpp files at all
- To avoid name mangling
Answer: The compiler needs the full body visible where the template is used. Each concrete version is generated at the point of use, so the full definition must be visible there — hiding it in a .cpp causes undefined-reference linker errors.
What does maxOf(5, 3.14) cause, given template <typename T> T maxOf(T a, T b)?
- T = double automatically
- T = int automatically
- A deduction failure — T can't be both int and double
- A runtime exception
Answer: A deduction failure — T can't be both int and double. One argument is int, the other double, so T cannot be deduced to a single type. Make the types match or force maxOf<double>(5, 3.14).