Followers

Friday, November 10, 2023

Template in C++

 

In C++, a template is a feature that allows us to write generic programs. It enables us to create functions and classes that work with any data type. Templates provide a way to write code once and use it with different types without having to duplicate the code for each type.

There are two main types of templates in C++:

1. Function Templates:

Function templates allow us to define a generic function that can operate on different data types. The syntax for a function template is:

cpp
template <typename T> T myFunction(T param) { // Function body // ... }

2. Class Templates:

Class templates allow us to create a generic class that can work with different data types. The syntax for a class template is:

cpp
template <typename T> class MyClass { public: T member; // Constructor MyClass(T value) : member(value) {} // Member function T getValue() const { return member; } };


Here's a simple example of a function template in C++:

cpp
#include <iostream> using namespace std; // Function template for finding the maximum of two values template <typename T> T max(T a, T b) { return (a > b) ? a : b; } int main() { // Example with integers int intMax = max(3, 7); cout << "Max of 3 and 7 is: " << intMax << endl; // Example with floating-point numbers double doubleMax = max(4.5, 2.3); cout << "Max of 4.5 and 2.3 is: " << doubleMax << endl; // Example with strings string strMax = max("apple", "orange"); cout << "Max of 'apple' and 'orange' is: " << strMax << endl; return 0; }

In this example, the max function is a template that can work with different data types (int, double, std::string, etc.). The <typename T> declares a template parameter T, which is a placeholder for the actual type. When we use the function, the compiler automatically generates the appropriate code for the given data types.

Similarly, you can create class templates. Here's an example of a simple template class:

cpp
#include <iostream> using namespace std; // Template class for a generic pair template <typename T, typename U> class Pair { public: T first; U second; Pair(T a, U b) : first(a), second(b) {} }; int main() { // Example with integers and strings Pair<int, string> myPair(1, "apple"); cout << "Pair: " << myPair.first << ", " << myPair.second << endl; return 0; }

In this case, the Pair class is a template that can hold a pair of values of different types. When we create an instance of Pair, we specify the types for the template parameters (int and std::string in this example).

Templates are a powerful feature in C++ that enable us to write flexible and reusable code. They are widely used in the standard library and are essential for creating generic algorithms and data structures.

Exception handling in C++


Exception handling in C++ is a powerful mechanism that allows us to deal with exceptional conditions or errors in our code in a structured and efficient manner. It provides a way to separate the normal flow of our program from error-handling logic. Exception handling is an essential feature for writing robust and reliable software. In C++, exception handling is done through try, throw, and catch keywords.

The Basics of Exception Handling:

  1. 1. Try: In C++, we define a try block to enclose the code that may potentially throw an exception. This block is used to identify the region where an exception can be thrown.

  2. 2. Throw: When an exceptional situation occurs within the try block, we can use the throw keyword to raise an exception. We can throw any object as an exception, but it is often best to use objects of classes derived from the standard library's std::exception class.

  3. 3. Catch: We use a catch block to specify the type of exception we want to catch and how to handle it. Multiple catch blocks can be used to catch different types of exceptions. Once an exception is caught, the corresponding catch block is executed.

Example 1: Basic Exception Handling

cpp
#include <iostream> using namespace std; int main() { try { int num = 10; if (num > 5) { throw "Number is greater than 5"; } } catch (const char* message) { cerr << "Exception caught: " << message << endl; } return 0; }

In this example, we use a try block to catch an exception (a C-style string) thrown when num is greater than 5. The catch block handles the exception and prints an error message.

Example 2: Multiple Catch Blocks

cpp
#include <iostream> #include <stdexcept> using namespace std; int main() { try { int num = 10; if (num > 5) { throw runtime_error("Number is greater than 5"); } } catch (const char* message) { cerr << "Caught a char* exception: " << message << endl; } catch (const exception& e) { cerr << "Caught an exception: " << e.what() << endl; } return 0; }

Here, we throw an exception of type std::runtime_error and catch it with two different catch blocks—one for const char* and one for std::exception. The latter is a more general catch block that can catch any exception derived from std::exception.

Example 3: Exception Propagation

cpp
#include <iostream> #include <stdexcept> using namespace std; void someFunction() { try { throw runtime_error("An error occurred."); } catch (const exception& e) { cerr << "Exception caught in someFunction: " << e.what() << endl; throw; // Re-throw the same exception } } int main() { try { someFunction(); } catch (const exception& e) { cerr << "Exception caught in main: " << e.what() << endl; } return 0; }

In this example, the someFunction throws an exception, and the main function catches and re-throws it. This allows us to propagate exceptions up the call stack to be handled at an appropriate level.