Templates
Generic programming with function and class templates
📐 What are Templates?
Templates enable generic programming in C++. They allow you to write code that works with any data type, creating reusable functions and classes that adapt to different types at compile time.
// Function template example
template<typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}
Key Template Concepts
Function Templates
Function templates enable you to write a single, generic function that works with multiple data types, using
placeholder types specified with the template<typename T> syntax. The compiler
generates
type-specific versions as needed. For instance, a getMax(T a, T b) template can compare integers,
doubles, characters, or even custom objects, returning the larger value. This promotes code reuse, reduces
duplication, and ensures type safety. Templates are a cornerstone of generic programming in C++, allowing operations
like swapping pairs or printing arrays to be defined once yet applied universally.
template<typename T>
T add(T a, T b) { return a + b; }
Class Templates
Generic classes for different data types
template<typename T>
class Stack { /* ... */ };
Compile-time
Templates are resolved at compile time
Stack<int> intStack;
Stack<string> stringStack;
Type Safety
Maintains type safety while being generic
vector<int> numbers;
vector<string> words;
🔹 Function Templates
Function templates enable you to write a single, generic function that works with multiple data types, using
placeholder types specified with the template<typename T> syntax. The compiler
generates
type-specific versions as needed. For instance, a getMax(T a, T b) template can compare integers,
doubles, characters, or even custom objects, returning the larger value. This promotes code reuse, reduces
duplication, and ensures type safety. Templates are a cornerstone of generic programming in C++, allowing operations
like swapping pairs or printing arrays to be defined once yet applied universally.
#include <iostream>
using namespace std;
// Basic function template
template<typename T>
T getMax(T a, T b) {
return (a > b) ? a : b;
}
// Function template with multiple parameters
template<typename T, typename U>
void printPair(T first, U second) {
cout << "First: " << first << ", Second: " << second << endl;
}
// Template with non-type parameter
template<typename T, int SIZE>
void printArray(T arr[]) {
for (int i = 0; i < SIZE; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
// Automatic type deduction
cout << getMax(10, 20) << endl; // int
cout << getMax(3.14, 2.71) << endl; // double
cout << getMax('a', 'z') << endl; // char
// Explicit type specification
cout << getMax<double>(10, 20.5) << endl;
// Multiple template parameters
printPair(42, "Hello");
printPair(3.14, true);
// Non-type template parameter
int numbers[] = {1, 2, 3, 4, 5};
printArray<int, 5>(numbers);
return 0;
}
Output:
20
3.14
z
20.5
First: 42, Second: Hello
First: 3.14, Second: 1
1 2 3 4 5
🔹 Class Templates
Create generic classes that can work with different data types:
#include <iostream>
#include <vector>
using namespace std;
// Basic class template
template<typename T>
class Box {
private:
T content;
public:
Box(T item) : content(item) {}
T getContent() const {
return content;
}
void setContent(T item) {
content = item;
}
void display() const {
cout << "Box contains: " << content << endl;
}
};
// Class template with multiple parameters
template<typename T, int CAPACITY>
class FixedArray {
private:
T data[CAPACITY];
int size;
public:
FixedArray() : size(0) {}
bool add(T item) {
if (size < CAPACITY) {
data[size++] = item;
return true;
}
return false;
}
T get(int index) const {
if (index >= 0 && index < size) {
return data[index];
}
throw out_of_range("Index out of range");
}
int getSize() const { return size; }
int getCapacity() const { return CAPACITY; }
};
int main() {
// Using Box template with different types
Box<int> intBox(42);
Box<string> stringBox("Hello Templates!");
Box<double> doubleBox(3.14159);
intBox.display();
stringBox.display();
doubleBox.display();
// Using FixedArray template
FixedArray<int, 5> numbers;
numbers.add(10);
numbers.add(20);
numbers.add(30);
cout << "Array size: " << numbers.getSize() << endl;
cout << "Array capacity: " << numbers.getCapacity() << endl;
cout << "First element: " << numbers.get(0) << endl;
return 0;
}
Output:
Box contains: 42
Box contains: Hello Templates!
Box contains: 3.14159
Array size: 3
Array capacity: 5
First element: 10
🔹 Template Specialization Preview
Templates can be specialized for specific types:
// Generic template
template<typename T>
class Printer {
public:
void print(T value) {
cout << "Generic: " << value << endl;
}
};
// Specialized template for strings
template<>
class Printer<string> {
public:
void print(string value) {
cout << "String: \"" << value << "\"" << endl;
}
};
int main() {
Printer<int> intPrinter;
Printer<string> stringPrinter;
intPrinter.print(42); // Uses generic template
stringPrinter.print("Hello"); // Uses specialized template
return 0;
}
Output:
Generic: 42
String: "Hello"