Generics and Containers

COS2614 - Programming: Contemporary Concepts · Higher-Level Programming

Generics and Containers

Generics and containers are essential concepts in programming that allow you to create flexible and reusable code. Generics enable you to define functions and classes with placeholder types, while containers are data structures that hold collections of objects. Understanding these concepts is crucial for writing efficient and maintainable code.

Key idea: After studying this topic, you should be able to:

  • Explain the concept of generics in programming.
  • Describe different types of containers and their uses.
  • Implement a simple generic container class.
  • Use generics to create functions that work with different data types.

Understanding Generics

Generics allow you to write code that is type agnostic. This means you can create classes and functions that can operate on any data type without being tied to a specific one. In C++, generics are often implemented using templates.

Templates in C++

A template is a blueprint for creating a function or class. You define a template using the template keyword followed by template parameters in angle brackets. Here is an example of a simple template function:

template <typename T>
void printValue(T value) {
std::cout << value << std::endl;
}

This function can print any type of value passed to it, such as an integer, a double, or a string.

Example of a Template Function

Let us look at an example of a function that uses a template:

#include <iostream>
template <typename T>
void display(T item) {
std::cout << "Item: " << item << std::endl;
}
int main() {
display(5); // Displays an integer
display(3.14); // Displays a double
display("Hello"); // Displays a string
return 0;
}

This code demonstrates how the display function can accept different types of arguments.

Containers in C++

Containers are data structures that store collections of objects. They help manage groups of data efficiently. C++ Standard Template Library (STL) provides several types of containers, including:

  • Vector: A dynamic array that can grow in size.
  • List: A doubly linked list that allows for efficient insertions and deletions.
  • Map: A collection of key-value pairs that provides fast lookups based on keys.

Using a Vector

Vectors are one of the most commonly used containers. You can easily add, remove, and access elements. Here is an example of using a vector:

#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers;
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
for(int num : numbers) {
std::cout << num << std::endl;
}
return 0;
}

This code creates a vector of integers, adds three numbers, and prints them.

Using a Map

Maps store key-value pairs. Here is how you can use a map:

#include <iostream>
#include <map>
int main() {
std::map<std::string, int> ageMap;
ageMap["Alice"] = 30;
ageMap["Bob"] = 25;
for(const auto &pair : ageMap) {
std::cout << pair.first << " is " << pair.second << " years old." << std::endl;
}
return 0;
}

This code creates a map that associates names with ages and prints each name with its corresponding age.

Creating a Generic Container Class

You can create a generic container class using templates. Here is a simple implementation of a generic stack:

#include <iostream>
#include <vector>
template <typename T>
class Stack {
private:
std::vector<T> elements;
public:
void push(const T& element) {
elements.push_back(element);
}
void pop() {
if (!elements.empty()) {
elements.pop_back();
}
}
T top() const {
return elements.back();
}
};
int main() {
Stack<int> intStack;
intStack.push(1);
intStack.push(2);
std::cout << intStack.top() << std::endl; // Outputs 2
return 0;
}

This stack class allows you to store elements of any type.

Watch out: When using generics, ensure that the operations you perform on the generic type are valid. For example, you cannot perform arithmetic operations on a generic type without ensuring it supports those operations.

Summary

  • Generics allow you to write flexible and reusable code using templates.
  • Containers are data structures that hold collections of objects, such as vectors and maps.
  • You can create generic classes and functions to work with different data types.

Check your understanding

  1. What is a template in C++?
  2. How do you declare a vector and add elements to it?
  3. What are the advantages of using a map over a vector?
  4. How can you implement a generic container class in C++?