Templates, exception handling and the standard template library notes — Unit 5
Free unit-wise study notes on templates, exception handling and the standard template library for Object Oriented Programming with C++, Semester 2 of B.Tech — Computer Science & Engineering — key concepts, examples, important questions and a revision checklist for semester exams.
An exhaustive guide to Generic Programming and Safety. Covers the syntax and instantiation of Templates, the architecture of Exception Handling, and a deep-dive into the Standard Template Library (STL).
Notebook — 14 pages
Page 1
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
1. The Need for Generics
Throughout the previous units, C++ enforced strict type checking. An `int` is an `int`, a `float` is a `float`. If you write a function to swap two integers, and later need to swap two floats, you must write a completely new, overloaded function.
The logic `t=a; a=b; b=t;` is completely identical across all three functions. Rewriting the exact same logic just to change the data type violates the DRY (Don't Repeat Yourself) principle. It bloats the codebase and makes maintenance a nightmare.
⇒The Solution: Templates
Templates introduce Generic Programming. They allow you to write a function or a class ONCE, using a placeholder for the data type. The compiler automatically generates the correct type-specific code when you actually use it.
Page 2
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
2. Function Templates
A Function Template acts as a blueprint for generating standard functions. We define a generic type parameter (usually `T`) that the compiler will replace with the actual type at runtime.
Syntax of a Function Template
// 'template' keyword followed by angle brackets
template <class T> // OR template <typename T>
void swapValues(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
⇒How it works: Instantiation
When you call `swapValues(x, y)` where `x` and `y` are integers, the compiler sees the `int` arguments. It silently writes a hidden `int` version of the function into the compiled machine code. If you later call it with `float`, it writes a hidden `float` version.
Implicit Instantiation: The compiler guesses the type based on the arguments passed: `swapValues(10, 20);`
Explicit Instantiation: You force the compiler to use a specific type: `swapValues<float>(10.5, 20.5);`
Page 3
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
3. Multiple Template Parameters
A template is not restricted to a single placeholder type. You can define as many generic types as necessary for your logic.
You can overload a template function with a normal, non-template function. If the compiler finds an EXACT match with the non-template function, it executes that one. If no exact match is found, it instantiates the template.
Page 4
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
4. Class Templates
Just as functions can be generic, entire classes can be generic. This is exceptionally useful for Data Structures. A Stack logic (push, pop, Top) is identical whether it's a Stack of integers, a Stack of floats, or a Stack of custom `Employee` objects.
Defining a Class Template
template <class T>
class Box {
T content;
public:
void setContent(T val) { content = val; }
T getContent() { return content; }
};
int main() {
// MUST explicitly state the type when creating objects!
Box<int> intBox;
intBox.setContent(100);
Box<string> strBox;
strBox.setContent("Secrets");
}
Page 5
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
5. Non-Type Template Args
Template parameters don't always have to be data types. They can also be constant primitive values (usually integers) evaluated at compile-time. These are called Non-Type Template Arguments.
Passing an array size at compile-time
// T is a type, SIZE is a constant integer
template <class T, int SIZE>
class StaticArray {
T arr[SIZE]; // Array size fixed at compile time!
public:
void fill(T val) {
for(int i=0; i<SIZE; i++) arr[i] = val;
}
};
int main() {
// Creates an array of 50 integers
StaticArray<int, 50> myInts;
// Creates an array of 10 floats
StaticArray<float, 10> myFloats;
}
This is vastly superior to dynamic allocation (`new T[size]`) when the size is known beforehand, because the memory is allocated safely on the stack without runtime overhead.
Page 6
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
6. Exception Handling
Errors occur in software. Some are syntax errors (caught by the compiler). Some are logical errors (bugs). But Exceptions are anomalous runtime conditions that interrupt the normal flow of the program (e.g., dividing by zero, file not found, memory exhausted).
⇒The C-Style Error Problem
In C, errors were handled by returning error codes (e.g., `-1` for failure). This forced developers to write `if(result == -1)` after EVERY function call, cluttering the code and making it easy to accidentally ignore a critical error.
⇒The C++ Try-Catch Mechanism
C++ separates the error-reporting logic from the error-handling logic using three powerful keywords: `try`, `throw`, and `catch`.
TRY
Encloses the risky code that might fail.
THROW
If an error occurs, the code 'throws' an exception object into the air.
CATCH
The execution instantly jumps to the catch block, which 'catches' the object and handles the crisis.
Page 7
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
7. Try, Throw, Catch Syntax
A classic division by zero guard
int main() {
int a = 10, b = 0;
try {
if (b == 0) {
// 1. Error detected! Throw an exception (can be any type)
throw "Division by Zero Error!";
}
// 2. This code NEVER executes if throw happens
cout << "Result: " << (a / b);
}
catch (const char* errorMessage) {
// 3. Execution jumps here immediately
cout << "FATAL ALERT: " << errorMessage;
}
// 4. Program continues running normally after catch!
cout << "Program recovering...";
}
⇒The Unwinding Process
When a `throw` occurs, the system immediately halts the current function. It begins 'Stack Unwinding', destroying all local objects safely (calling their destructors) as it travels back up the call stack looking for a matching `catch` block.
Page 8
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
8. Multiple Catch Blocks
A single `try` block can contain various risky operations that throw completely different types of exceptions (e.g., an `int` error code, a `string` error message, or a custom class). You can chain multiple `catch` blocks to handle each specific type.
try {
// Code that might throw int or const char*
}
catch (int errorCode) {
cout << "Numerical Error ID: " << errorCode;
}
catch (const char* msg) {
cout << "String Error: " << msg;
}
catch (...) {
// The 'Catch-All' Block!
// MUST be placed at the very end of the chain.
cout << "An unknown error occurred!";
}
Page 9
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
9. Exception Specifications
In large systems, if you are calling a function written by someone else, you need to know exactly what exceptions it might throw so you can write the correct `catch` blocks. C++ historically provided Exception Specifications.
Restricting what a function can throw (Legacy C++)
// This function is ONLY allowed to throw integers or doubles
void processData() throw(int, double) {
// ...
}
// This function guarantees it will NEVER throw an exception
void safeFunction() throw() {
// ...
}
⇒Modern C++ and 'noexcept'
The old `throw(...)` specifications were deprecated in C++11 because they caused runtime overhead. Modern C++ replaced them entirely with the `noexcept` keyword.
Writing `void myFunc() noexcept;` is an ironclad guarantee to the compiler that the function will never throw. The compiler can drastically optimize the machine code because it doesn't need to generate Stack Unwinding safety nets.
Page 10
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
10. The Standard Template Library
The Standard Template Library (STL) is the crown jewel of C++. It is a massive library of generic, highly optimized templates for data structures and algorithms. Using the STL transforms C++ from a low-level systems language into a highly productive modern language.
⇒The Three Pillars of STL
Containers
Data structures that hold collections of objects (Vector, List, Map).
Algorithms
Pre-written logic to process the data (Sort, Search, Reverse).
Iterators
Specialized pointers that bridge Containers and Algorithms.
The genius of the STL is orthogonal design: The algorithms are completely decoupled from the containers. You can use the exact same `std::sort` algorithm to sort a `vector`, a `list`, or a standard array, because the Iterators act as a universal adapter.
Page 11
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
11. STL Containers Overview
Containers physically store your data. They manage memory allocation automatically.
Sequence Containers
Store data linearly. (e.g., `vector`, `list`, `deque`)
Associative Containers
Store data in sorted tree structures for fast retrieval. (e.g., `set`, `map`)
Derived Containers
Adapt sequences for specific behaviors. (e.g., `stack`, `queue`)
⇒The Almighty Vector
The `std::vector` is a dynamic array. Unlike standard arrays, it automatically resizes itself when you add too many elements.
#include <vector>
vector<int> scores; // Creates an empty vector
scores.push_back(95); // Adds to the end, resizes if needed
scores.push_back(80);
cout << "Size: " << scores.size(); // 2
Page 12
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
12. Algorithms & Iterators
⇒Iterators
An Iterator behaves exactly like a pointer, but it is smart enough to traverse complex internal structures (like trees or linked lists) using simple `++` operations.
Traversing a container using Iterators
vector<int> v = {10, 20, 30};
vector<int>::iterator ptr;
for(ptr = v.begin(); ptr != v.end(); ptr++) {
cout << *ptr << " "; // Dereference to get value
}
⇒Algorithms
Included via `#include <algorithm>`, these are highly optimized global functions.
Sorting a vector with one line
#include <algorithm>
// ...
vector<int> v = {50, 10, 40};
// Pass the start iterator and end iterator
sort(v.begin(), v.end()); // v is now {10, 40, 50}
Page 13
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
13. Advanced STL: The Map
A `std::map` is an associative container that stores elements in Key-Value pairs. It automatically sorts the pairs based on the Key using a balanced binary tree (Red-Black Tree) internally.
Using a Map as a Dictionary
#include <map>
int main() {
// Key is string, Value is int
map<string, int> directory;
// Insertion
directory["Alice"] = 9876;
directory["Bob"] = 1234;
// Fast retrieval (O(log n) time complexity)
cout << "Bob's number: " << directory["Bob"];
// Iterating through a map
for(auto it = directory.begin(); it != directory.end(); it++) {
// Iterators point to a 'pair' struct with 'first' and 'second'
cout << it->first << " : " << it->second;
}
}
Maps are universally asked in coding interviews for frequency counting and caching problems.
Page 14
Wink Notes
B.Tech CSE — 2nd Semester
Object Oriented Programming with C++
— Unit - 5 —
14. Unit 5 Revision Checklist
⇒End-of-Unit Verification
Explain how Templates implement Generic Programming and solve the DRY principle.
Write the syntax for a Function Template to swap two generic variables.
Explain the difference between implicit and explicit template instantiation.
Write the syntax for a Class Template modeling a generic Stack.
Explain Non-Type Template Arguments and why they are evaluated at compile-time.
Explain the separation of logic provided by `try`, `throw`, and `catch` blocks.
Describe 'Stack Unwinding' during an exception throw.
Write a multi-catch block, ensuring the 'catch-all' block `catch(...)` is positioned correctly.
Explain the performance difference between `throw(...)` specifications and the modern `noexcept` keyword.
List the 3 pillars of the STL and explain how Iterators connect Containers to Algorithms.
Write a program to create a `vector`, add elements to it, and sort it using `std::sort`.