Reading — step 1 of 7
Learn
Templates let you write code that works for any type. The compiler generates a specialized version for each type you use. C++'s killer feature for type-safe generic code.
Function templates
template <typename T>
T max_of(T a, T b) {
return a > b ? a : b;
}
int x = max_of(3, 7); // T deduced as int
double y = max_of(3.5, 2.1); // T deduced as double
std::string s = max_of<std::string>("hello", "world"); // explicit
The compiler stamps out a max_of<int>, max_of<double>, and max_of<std::string> — one per type you use. Each is type-checked separately.
Class templates
template <typename T>
class Stack {
public:
void push(T value) { data_.push_back(std::move(value)); }
T pop() { T t = std::move(data_.back()); data_.pop_back(); return t; }
bool empty() const { return data_.empty(); }
private:
std::vector<T> data_;
};
Stack<int> intStack;
Stack<std::string> stringStack;
The whole STL is built on class templates — vector<T>, map<K, V>, unique_ptr<T>, etc.
Multiple type parameters
template <typename K, typename V>
struct Pair {
K first;
V second;
};
Pair<std::string, int> p{"Alice", 30};
Non-type template parameters
Templates can take constants, not just types:
template <typename T, size_t N>
class FixedArray {
T data[N];
public:
size_t size() const { return N; }
};
FixedArray<int, 10> arr; // 10 ints, size known at compile time
std::array<T, N> works exactly this way.
Concepts (C++20) — constraining templates
In modern C++, you can require types to satisfy specific concepts:
#include <concepts>
template <std::integral T>
T abs_val(T x) { return x < 0 ? -x : x; }
abs_val(5); // ✓ int satisfies integral
// abs_val(3.14); // ✗ compile error — double is not integral
Without concepts, template errors are notoriously cryptic — concepts give clean error messages and document intent.
Most Judge0 setups don't yet support C++20 concepts; older code uses SFINAE or static_assert.
Compile-time vs runtime
Template code is COMPILED, not runtime-dispatched. Compiler generates one version per instantiation:
max_of(3, 7); // generates max_of<int>
max_of(3.5, 2.1); // generates max_of<double>
Both versions exist in the compiled binary. Templates trade compile time and binary size for runtime speed — no virtual dispatch, fully inlinable.
Common mistakes
- Putting template definitions in a .cpp file — usually causes link errors. Templates need their full definition visible to every translation unit that uses them. Define in headers.
- Mixing types the template wasn't designed for — error messages can be cryptic. Concepts (C++20) help.
typenamevsclass— interchangeable in most contexts:template <typename T>andtemplate <class T>are the same.- Excessive instantiation — bloats binary size. Be deliberate about which types you use.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…