Generics in C++ allow functions and classes to work with different data types using a single implementation. C++ implements generics through templates, enabling reusable, flexible, and type-safe code.
- Write type-independent code using templates.
- Reduce code duplication and improve maintainability.
- Support both built-in and user-defined data types.
Templates in C++
Templates are the mechanism used to implement generics in C++. They allow data types to be passed as parameters to functions and classes.
Function Templates
A function template allows a single function definition to work with multiple data types.
#include <iostream>
using namespace std;
// One function works for all data types.
// This would work even for user defined types
// if operator '>' is overloaded
template <typename T>
T myMax(T x, T y)
{
return (x > y) ? x : y;
}
int main()
{
// Call myMax for int
cout << myMax<int>(3, 7) << endl;
// call myMax for double
cout << myMax<double>(3.0, 7.0) << endl;
// call myMax for char
cout << myMax<char>('g', 'e') << endl;
return 0;
}
Output
7 7 g
Explanation: The compiler generates the required version of the function based on the type used when calling it.
Class Templates
A class template allows a class to operate on different data types without rewriting the class definition.
#include <iostream>
using namespace std;
template <typename T>
class Array {
private:
T* ptr;
int size;
public:
Array(T arr[], int s);
void print();
};
template <typename T>
Array<T>::Array(T arr[], int s)
{
ptr = new T[s];
size = s;
for (int i = 0; i < size; i++)
ptr[i] = arr[i];
}
template <typename T>
void Array<T>::print()
{
for (int i = 0; i < size; i++)
cout << " " << *(ptr + i);
cout << endl;
}
int main()
{
int arr[5] = { 1, 2, 3, 4, 5 };
Array<int> a(arr, 5);
a.print();
return 0;
}
Output
1 2 3 4 5
Explanation: The same class can be instantiated for different data types such as int, float, char, or user-defined types.
Templates with Multiple Parameters
Templates can take more than one type parameter, enabling classes and functions to handle multiple data types within a single generic implementation.
#include <iostream>
using namespace std;
template <class T, class U>
class A {
T x;
U y;
public:
A()
{
cout << "Constructor Called" << endl;
}
};
int main()
{
A<char, char> a;
A<int, double> b;
return 0;
}
Output
Constructor Called Constructor Called
Explanation: Multiple template parameters allow a class or function to work with different types simultaneously.
Advantages of Generics
Generics improve flexibility and reusability by allowing the same code to work with multiple data types.
- Improves code reuse and reduces duplication by using a single implementation for different data types.
- Provides compile-time type safety while supporting both built-in and user-defined types.
- Simplifies maintenance and forms the foundation of the Standard Template Library (STL).
Limitations of Generics
Although powerful, templates can introduce some complexity.
- Compiler error messages can be lengthy and sometimes difficult to understand.
- Heavy use of templates may increase compilation time and executable size.
- Complex template code can reduce readability and be harder to maintain.