C++ — Templates
Function templates
#include <iostream>
using namespace std;
template <typename T>
T maximum(T a, T b) {
return (a > b) ? a : b;
}
int main() {
cout << maximum(3, 7) << endl; // 7 (int)
cout << maximum(3.14, 2.72) << endl; // 3.14 (double)
cout << maximum('a', 'z') << endl; // z (char)
return 0;
}
Multiple template parameters
#include <iostream>
using namespace std;
template <typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
return a + b;
}
int main() {
cout << add(3, 4) << endl; // 7
cout << add(3.14, 2) << endl; // 5.14
cout << add(string("Hello"), string(" World")) << endl;
return 0;
}
Class templates
#include <iostream>
using namespace std;
template <typename T>
class Stack {
private:
static const int MAX = 100;
T data[MAX];
int top;
public:
Stack() : top(-1) {}
void push(T value) {
if (top < MAX - 1) {
data[++top] = value;
}
}
T pop() {
if (top >= 0) {
return data[top--];
}
throw runtime_error("Stack underflow");
}
bool isEmpty() const { return top == -1; }
int size() const { return top + 1; }
};
int main() {
Stack<int> intStack;
intStack.push(10);
intStack.push(20);
cout << intStack.pop() << endl; // 20
Stack<string> strStack;
strStack.push("Hello");
strStack.push("World");
cout << strStack.pop() << endl; // World
return 0;
}
Non-type template parameters
#include <iostream>
using namespace std;
template <typename T, int N>
class Array {
private:
T data[N];
public:
void set(int index, T value) {
if (index >= 0 && index < N) {
data[index] = value;
}
}
T get(int index) const {
return data[index];
}
int size() const { return N; }
};
int main() {
Array<int, 5> arr;
for (int i = 0; i < 5; i++) {
arr.set(i, i * 10);
}
for (int i = 0; i < arr.size(); i++) {
cout << arr.get(i) << " ";
}
cout << endl; // 0 10 20 30 40
return 0;
}
Template specialization
#include <iostream>
#include <cstring>
using namespace std;
// Generic version
template <typename T>
bool isEqual(T a, T b) {
return a == b;
}
// Specialization for C-strings
template <>
bool isEqual<const char *>(const char *a, const char *b) {
return strcmp(a, b) == 0;
}
int main() {
cout << isEqual(5, 5) << endl; // 1 (int)
cout << isEqual(3.14, 3.14) << endl; // 1 (double)
cout << isEqual("hello", "hello") << endl; // 1 (const char*)
cout << isEqual("hello", "world") << endl; // 0
return 0;
}
Variadic templates (C++11)
#include <iostream>
using namespace std;
// Base case
void print() {
cout << endl;
}
// Recursive case
template <typename T, typename... Args>
void print(T first, Args... rest) {
cout << first << " ";
print(rest...);
}
int main() {
print(1, 2, 3); // 1 2 3
print("Hello", 3.14, 'A'); // Hello 3.14 A
return 0;
}
SFINAE and enable_if
#include <iostream>
#include <type_traits>
using namespace std;
// Only enabled for integral types
template <typename T>
typename enable_if<is_integral<T>::value, T>::type
safeDivide(T a, T b) {
if (b == 0) throw runtime_error("Division by zero");
return a / b;
}
// Only enabled for floating-point types
template <typename T>
typename enable_if<is_floating_point<T>::value, T>::type
safeDivide(T a, T b) {
return a / b; // No exception for floating point
}
int main() {
cout << safeDivide(10, 3) << endl; // 3 (int)
cout << safeDivide(10.0, 3.0) << endl; // 3.33333 (double)
return 0;
}
Concept constraints (C++20)
#include <iostream>
#include <concepts>
using namespace std;
template <typename T>
concept Numeric = is_arithmetic_v<T>;
template <Numeric T>
T square(T x) {
return x * x;
}
template <typename T>
concept Printable = requires(T t) {
{ cout << t } -> same_as<ostream &>;
};
template <Printable T>
void print(T value) {
cout << value << endl;
}
int main() {
cout << square(5) << endl; // 25
cout << square(3.14) << endl; // 9.8596
print("Hello");
return 0;
}
Mini Practice
Write C++ code that:
- Creates a function template that finds the minimum of two values
- Creates a class template for a simple Pair
- Specializes the Pair template for strings
- Uses a variadic template to print any number of arguments
Up Next
In the next lesson, you'll learn about STL — the Standard Template Library containers and algorithms.
Related Topics
Frequently Asked Questions about Templates
What is Templates in C++?
Templates is a fundamental concept in C++. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Templates?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Templates.
Why is Templates important in C++?
Templates is essential for C++ development. Understanding this concept will help you write better code and solve real-world problems more effectively.