This section explores generic programming in C++, which allows writing flexible, reusable code using templates. We also discuss exception handling, which is used to handle errors gracefully using try, catch, and throw mechanisms.
1. Function Templates
A function template allows you to define a function that works with any data type. It acts as a blueprint for creating functions that can operate on different data types.
Syntax:
template <typename T>
T add(T a, T b) {
return a + b;
}
Example: Using function templates.
#include <iostream>
using namespace std;
template <typename T> // Function template for any type T
T add(T a, T b) {
return a + b;
}
int main() {
cout << add(5, 10) << endl; // Output: 15 (int)
cout << add(3.5, 2.5) << endl; // Output: 6.0 (double)
cout << add('A', 'B') << endl; // Output: 131 (char)
return 0;
}
Output:
15
6
131
2. Class Templates
A class template enables you to define a class that can operate with any data type.
Syntax:
template <typename T>
class MyClass {
T data;
public:
MyClass(T value) : data(value) {}
T getData() { return data; }
};
Example: Using class templates.
#include <iostream>
using namespace std;
template <typename T> // Class template
class MyClass {
T data;
public:
MyClass(T value) : data(value) {}
T getData() { return data; }
};
int main() {
MyClass<int> obj1(100); // T is int
MyClass<double> obj2(3.14); // T is double
cout << obj1.getData() << endl; // Output: 100
cout << obj2.getData() << endl; // Output: 3.14
return 0;
}
Output:
100
3.14
3. Standard Template Library (STL)
C++ provides the Standard Template Library (STL), which is a collection of template classes and functions. It provides useful data structures and algorithms, making it easier to work with collections of data.
Containers
Containers are used to store collections of data. Some common types are:
Vector: Dynamic array.
List: Doubly linked list.
Queue: FIFO structure.
Stack: LIFO structure.
Map: Key-value pair collection.
Example: Using a vector (dynamic array) container.
#include <iostream>
#include <vector> // Include vector header
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5}; // Initialize vector with values
// Iterating through vector
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " "; // Output: 1 2 3 4 5
}
cout << endl;
vec.push_back(6); // Adding element to the vector
cout << "Last element: " << vec.back() << endl; // Output: 6
return 0;
}
Output:
1 2 3 4 5
Last element: 6
Algorithms
The STL provides useful algorithms for operations like sorting, searching, and manipulating data structures.
Example: Using the sort algorithm to sort a vector.
#include <iostream>
#include <vector>
#include <algorithm> // Include for sorting algorithm
using namespace std;
int main() {
vector<int> vec = {5, 3, 8, 1, 2};
// Sorting the vector
sort(vec.begin(), vec.end()); // Sorting in ascending order
// Display sorted vector
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " "; // Output: 1 2 3 5 8
}
cout << endl;
return 0;
}
Output:
1 2 3 5 8
Iterators
Iterators are used to traverse through the elements of a container.
Example: Using iterators to traverse a vector.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {10, 20, 30, 40};
// Using iterator to access vector elements
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " "; // Output: 10 20 30 40
}
cout << endl;
return 0;
}
Output:
10 20 30 40
4. Exception Handling
Exception handling in C++ helps to manage errors during program execution using the try, catch, and throw mechanisms.
try: A block of code that might throw an exception.
catch: A block of code that handles the exception.
throw: Used to throw an exception.
Syntax:
try {
// Code that may throw an exception
}
catch (exception_type e) {
// Code to handle the exception
}
Example: Basic Exception Handling
#include <iostream>
using namespace std;
int divide(int a, int b) {
if (b == 0) {
throw "Division by zero error!"; // Throwing an exception
}
return a / b;
}
int main() {
try {
int result = divide(10, 0); // This will throw an exception
cout << "Result: " << result << endl;
}
catch (const char* msg) { // Catching the exception
cout << "Error: " << msg << endl; // Output: Error: Division by zero error!
}
return 0;
}
Output:
Error: Division by zero error!
Example: Multiple Exceptions
You can have multiple catch blocks to handle different exceptions.
#include <iostream>
using namespace std;
int divide(int a, int b) {
if (b == 0) {
throw "Division by zero error!";
}
if (a < 0 || b < 0) {
throw "Negative number error!";
}
return a / b;
}
int main() {
try {
int result = divide(-10, 0); // This will throw a negative number error
cout << "Result: " << result << endl;
}
catch (const char* msg) {
cout << "Error: " << msg << endl; // Output: Error: Negative number error!
}
return 0;
}
Output:
Error: Negative number error!
Conclusion
Function Templates: Allow you to create generic functions that can work with any data type.
Class Templates: Allow you to define classes that work with different data types, providing flexibility and reusability.
STL:
Containers: Store collections of data (e.g., vector, list, map).
Algorithms: Predefined functions like sort(), find(), reverse() to operate on data in containers.
Iterators: Used to traverse containers in a generic way.
Exception Handling: Handles errors using try, catch, and throw. It ensures that your program can recover gracefully from runtime errors, including handling multiple types of exceptions.