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).