C++ Templates Quiz: Deduction, Concepts and Traits Practice
Practise C++ generic programming with 13 questions and three programs on templates, CTAD, specialisation, fold expressions, concepts and traits.
- Course: C++ study plan
- Module: Templates and generic programming
- Kind: Checkpoint — cleared at 70%
- Reading time: 28 min
- Runtime: Clang 18 · C++20
Checkpoint — Templates and generic programming is the checkpoint that closes the Templates and generic programming module: a graded quiz and whole-program exercises, passed at 70%.
Instructions
This checkpoint covers the whole module: function templates and deduction, class templates with out-of-class members and CTAD, full and partial specialisation and the traits pattern, non-type parameters and packs with fold expressions, concepts and constrained auto, and the type traits behind if constexpr dispatch.
How it works. Thirteen questions and three programs. You need 70% on the questions and every program accepted to clear the module. You can retake it as often as you like; your best score counts.
Before you start, make sure you can answer these from memory:
- Why does
max_of(3, 2.5)fail to compile, and what are the two ways to fix it? - Why must a template's definition live in the header rather than a
.cppfile? - What does
std::vector v{3}deduce, and how many elements does it hold? - Why is a function template overloaded rather than specialised?
- Which fold forms are legal on an empty pack?
- Is
boolastd::integral, and why does that matter for an overload set? - Why is
std::is_same_v<T, std::string>false insidef(T&& x)for astd::stringlvalue?
The three programs are a Queue<T> instantiated for the element type named on the first line, a statistics report whose overloads are chosen by concepts, and a Table<K, V> whose header line comes from a TypeName trait. Read the type word first; everything else follows from it.
Common questions
Why is a function template overloaded rather than specialised?
Because a full specialisation of a function template is not an overload candidate: the compiler picks the best primary template or non-template first, and a better-matching template can hide the specialisation. Function templates also cannot be partially specialised. A plain overload takes part in resolution and wins exact-match ties.
Which fold forms are legal on an empty pack?
Every binary fold, such as (0 + ... + xs), because it supplies its own initial value. Among unary folds, only those over &&, || and the comma operator, which give true, false and nothing. (xs + ...) on an empty pack does not compile.
Is bool a std::integral, and why does that matter?
Yes — bool is an integer type to the language, so it satisfies std::integral. In an overload set constrained on std::integral, a bool argument therefore picks the integer overload; add && !std::same_as<T, bool> when bool must go elsewhere.
Exercises
Queue<T> for the element type on the first line
Write a class template Queue<T> — first in, first out — over a std::vector<T> and a head index, with push, pop, front, size and print; define pop, front and print outside the class body with their own template headers. A function template run<T>() processes the commands; main reads the type word and calls run<int>() or run<std::string>().
Commands, one per line: push <v>; pop (print popped <v> or empty); front (print front=<v> or empty); size (print size=<k>); print (print queue: <front> … <back> or queue: (empty)).
Input: the type word (int or string), then commands. Output: one line per pop, front, size and print.
int
push 1
push 2
push 3
print
pop
front
size
prints
queue: 1 2 3
popped 1
front=2
size=2A statistics report chosen by concepts
Write a concept Number = std::integral<T> || std::floating_point<T>, a helper template <Number T> T spread(const std::vector<T>&) returning max - min, and three overloads of stats(const std::vector<T>& v):
template <std::integral T>:integral n=<k> sum=<sum> min=<min> max=<max> spread=<spread>— the sum in along long.template <std::floating_point T>:floating n=<k> mean=<mean> min=<min> max=<max> spread=<spread>— all four with two decimals.template <typename T>(unconstrained):text n=<k> longest=<word> chars=<total characters>— the first longest word on a tie.
Read n, then n lines of <type> <k> <v1> … <vk> with <type> one of int, double, string and k at least 1.
Input: n, then n lines. Output: one line per input line.
3
int 4 1 2 3 4
double 2 1.5 2.5
string 3 pear banana kiwi
prints
integral n=4 sum=10 min=1 max=4 spread=3
floating n=2 mean=2.00 min=1.50 max=2.50 spread=1.00
text n=3 longest=banana chars=14Table<K, V> with a TypeName header
Write a trait TypeName<T> — a primary template whose value is "unknown" and full specialisations giving "int", "double" and "std::string" — plus a variable template type_name_v<T>. Then a class template Table<K, V> over a std::map<K, V> with set(key, value) (a repeated key replaces the earlier value) and print(), which writes the header Table<<K name>, <V name>> from the trait, then every row in key order as <key> -> <value> (a double value with two decimals — use if constexpr on std::is_floating_point_v<V>), then rows=<count>.
The first line names K (int or string) and V (int, double or string), so there are six possible instantiations; dispatch through a run<K, V>() function template. Then n, then n lines of <key> <value>. Note that integer keys order numerically while string keys order lexicographically — the same input prints differently under Table<int, …> and Table<std::string, …>.
Input: the two type words, n, then n rows. Output: the header, the rows in key order, then rows=<count>.
int string
3
10 ten
2 two
7 seven
prints
Table<int, std::string>
2 -> two
7 -> seven
10 -> ten
rows=3In this module: Templates and generic programming
- Function templates — one definition, every type
- Class templates — Stack<T>, Pair<A, B> and deduction
- Specialisation — when one type needs its own version
- Non-type and variadic templates — numbers and packs as parameters
- Concepts and constraints — saying what T must be
- Type traits and metaprogramming — computing with types
- Checkpoint — Templates and generic programming (this lesson)
← Type traits and metaprogramming — computing with types · The container zoo — choosing a container →