Templates — function templates, class templates
WHY do templates exist?
Without templates you have three bad options:
- Copy-paste per type → duplicated code, bugs fixed in one copy not the others.
void*+ casts (the old C way) → loses type safety, you can mix up types silently.- Macros (
#define MAX(a,b)) → no type checking, ugly double-evaluation bugs.
Templates give you generic code that is still fully type-checked at compile time, with zero runtime overhead (the generated code is as fast as hand-written code).
Function Templates
HOW to write one — derive it from a concrete function
Start with a concrete version:
int maximum(int a, int b) { return (a > b) ? a : b; }Why generalize? The body never mentions int behaviour — it only needs > and copy.
So replace the type int with a placeholder name T:
template<typename T> // T is a type parameter
T maximum(T a, T b) { // works for ANY T that supports >
return (a > b) ? a : b;
}WHAT the compiler does (instantiation)
maximum(3, 7); // T deduced as int -> generates int maximum(int,int)
maximum(2.5, 1.1); // T deduced as double -> generates double maximum(double,double)
maximum<char>('a','z'); // T explicitly charWhy this step? The compiler looks at the arguments, deduces T, then generates code.
Nothing exists until you call it — an unused template generates no machine code at all.
Class Templates
HOW — build a tiny generic Box
template<typename T>
class Box {
T value; // member of the parameter type
public:
Box(T v) : value(v) {}
T get() const { return value; }
void set(T v) { value = v; }
};Why <T> everywhere a Box is named? Unlike functions, class templates usually cannot deduce
their type from a constructor (pre-C++17), so you must say the type:
Box<int> bi(42); // a concrete class Box<int> is generated
Box<string> bs("hi"); // a separate class Box<string> is generatedBox<int> and Box<string> are completely different types — they share no code at runtime.

Non-type template parameters & default args
A template parameter can be a compile-time value, not just a type:
template<typename T, int N> // N is a non-type parameter
class Array {
T data[N]; // size known at compile time -> stack-allocated
public:
int size() const { return N; }
};
Array<double, 5> a; // array of 5 doubles, N baked inWhy useful? N is known at compile time → no heap, bounds can be checked, fully inlined.
Default template arguments work too: template<typename T = int> class C {...}; → C<> x;.
Template Specialization (steel-manning "one size fits all")
Sometimes the generic version is wrong for one type. Specialization lets you override it:
template<typename T>
class Printer { public: void print(T x){ cout << x; } };
template<> // full specialization for bool
class Printer<bool> {
public:
void print(bool b){ cout << (b ? "true" : "false"); }
};Why? The generic cout << b prints 1/0; for bool we want words. The compiler picks the
most specialized match.
Flashcards
What is a template in C++?
What is template instantiation?
Why must template definitions live in header files?
Difference between template<class T> and template<typename T>?
Why does maximum(3, 2.5) fail to compile?
What is a non-type template parameter?
int N), not a type, e.g. Array<double,5>.Why does a class template usually need explicit <T> but a function template doesn't?
What is full template specialization?
template<>, chosen when that type is used.Do unused templates produce machine code?
What's the runtime overhead of templates?
Recall Feynman: explain to a 12-year-old
Imagine a cookie cutter shaped like a star. The cutter itself is not a cookie — it's a shape. You can press it into chocolate dough, sugar dough, or gingerbread dough and get a star cookie of each kind. A template is that cookie cutter: it describes the shape of the code. When you say "I want a Box of ints" or "max of two doubles," the compiler presses the cutter into that type and bakes a real, working piece of code. You wrote the shape once; the computer makes as many flavors as you need.
Connections
- Generic Programming — templates are C++'s mechanism for it.
- STL Containers —
vector,map,pairare all class templates. - Function Overloading — templates vs overloads; overload resolution picks between them.
- Macros vs Templates — why templates are type-safe and macros are not.
- Compile-time vs Runtime — instantiation happens at compile time → zero runtime cost.
- Type Deduction (auto) —
autoreuses the same deduction rules as function templates. - Template Specialization — overriding the generic blueprint for specific types.
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, template ka basic idea simple hai: tum same logic ko har type ke liye baar-baar mat likho.
Maan lo tumne max function int ke liye banaya, fir double ke liye copy-paste kiya, fir
string ke liye. Yeh bekaar hai — galti ek jagah fix karoge, doosri jagah reh jayegi. Template
bolta hai: "logic ek baar likho, type ko ek parameter bana do." template<typename T> likhne
se T ek placeholder ban jaata hai, aur jab tum maximum(3,7) call karte ho, compiler khud T
ko int samajh leta hai aur uske liye real function bana deta hai. Isko instantiation kehte
hain — bilkul cookie-cutter jaise, cutter shape hai, cookie alag-alag flavour ki ban-ti hai.
Function templates type ko arguments se deduce kar lete hain, lekin class templates mein
(C++17 se pehle) tumhe khud type batana padta hai — jaise Box<int> ya vector<double>. STL ka
poora vector, map, pair — sab class templates hi hain. Aur ek important baat: Box<int>
aur Box<string> bilkul alag types hain, runtime pe inka code share nahi hota.
Sabse bada exam/interview trap: log template ki definition .cpp file mein daal dete hain jaise
normal functions ke saath karte hain. Isse linker error aayega, kyunki compiler ko poora body
us file mein chahiye jahan template use ho raha hai. Isliye yaad rakho — template ki poori
definition header file (.h) mein rakho. Mnemonic simple: "WRITE once, STAMP per type, in the
HEADER." Aur best part — yeh sab compile-time pe hota hai, toh runtime overhead zero hai,
matlab hand-written code jitni hi speed.