Templates
Templates
Let's dive into each of these topics: templates, namespaces, and exception handling in
C++.
1. Templates:
Templates in C++ provide a way to create generic classes and functions that can work with any
data type. They allow you to write code once and use it with different types without having to
duplicate the code for each type.
Class Templates:
cpp
template <class T>
class Array {
private:
T* elements;
int size;
public:
Array(int s) : size(s) {
elements = new T[size];
}
T& operator[](int index) {
return elements[index];
}
~Array() {
delete[] elements;
}
};
In this example, Array is a class template that can be instantiated with any data type. The Array
class allows you to create an array of any type dynamically.
cpp
Array<int> intArray(5); // Creates an array of integers
Array<double> doubleArray(10); // Creates an array of doubles
Function Templates:
cpp
template <class T>
T max(T a, T b) {
return (a > b) ? a : b;
}
This function template max can accept arguments of any data type for which the comparison
operator > is defined.
cpp
int maxInt = max(5, 10); // Returns 10
double maxDouble = max(3.14, 2.71); // Returns 3.14
Templates are extensively used in the C++ Standard Template Library (STL) to provide generic
algorithms and data structures such as vectors, lists, and maps.
2. Namespaces:
Namespaces in C++ provide a way to group related code together and prevent name collisions.
They help in organizing code and avoiding conflicts between different parts of a program,
especially when dealing with large projects or using third-party libraries.
cpp
namespace Math {
const double PI = 3.14159;
double square(double x) {
return x * x;
}
}
In this example, Math is a namespace that contains constants and functions related to
mathematics. You can access members of the namespace using the scope resolution operator ::.
cpp
double area = Math::PI * Math::square(radius);
Namespaces are used to encapsulate code and avoid naming conflicts. They are particularly
useful when integrating multiple libraries or modules into a single project.
3. Exception Handling:
Exception handling in C++ provides a mechanism for handling errors and exceptional conditions
that occur during program execution. It allows you to separate error-handling code from normal
code, making your programs more robust and maintainable.
Try-Catch Blocks:
cpp
try {
// Code that might throw an exception
int result = divide(10, 0);
std::cout << "Result: " << result << std::endl;
} catch (const std::exception& ex) {
// Code to handle the exception
std::cerr << "Exception caught: " << ex.what() << std::endl;
}
In this example, divide is a function that might throw an exception if the second argument is
zero. The try block contains the code that might throw an exception, and the catch block
catches and handles the exception if it occurs.
Throwing Exceptions:
cpp
int divide(int a, int b) {
if (b == 0) {
throw std::invalid_argument("Division by zero");
}
return a / b;
}
Exception Specifications:
cpp
void processFile(const std::string& filename) throw(std::runtime_error) {
// Code to process the file
}
In this example, the processFile function specifies that it might throw a std::runtime_error
exception. This helps in documenting the exceptions that a function might throw and allows the
compiler to perform additional checks.
Exception handling is an essential feature of modern C++ programming, allowing you to write
robust and reliable code that gracefully handles errors and exceptional conditions. It helps in
improving the overall quality and maintainability of your software.