The C++ Standard Template Library (STL) is a powerful library that provides a variety of container classes, algorithms, and iterators to make programming more efficient and organized.
It includes several components, each with a specific purpose:
- Containers: Structures that store data.
- Algorithms: Functions that perform various operations on containers.
- Iterators: Objects that help traverse elements in containers.
Key Components of the C++ STL
- Containers: Include sequence containers (like vector, deque, list) and associative containers (set, map, etc.).
- Algorithms: Predefined functions that work on containers, such as sort, find, count, and reverse.
- Iterators: Objects that act as pointers to elements in containers, allowing traversal and manipulation.
1. Sequence Containers: vector
A vector is a dynamic array that can grow or shrink in size. It allows random access, making it efficient for accessing elements by index.
Example: Basic Operations with vector
#include <iostream> #include <vector> using namespace std; int main() { vector<int> numbers = {1, 2, 3}; // Adding elements numbers.push_back(4); numbers.push_back(5); // Accessing elements cout << "Elements: "; for (int num : numbers) { cout << num << " "; } cout << endl; // Removing the last element numbers.pop_back(); cout << "After pop_back: "; for (int num : numbers) { cout << num << " "; } cout << endl; return 0; }
Output:
Elements: 1 2 3 4 5 After pop_back: 1 2 3 4
2. Sequence Containers: deque
A deque (double-ended queue) allows fast insertion and deletion at both the beginning and the end.
Example: Basic Operations with deque
#include <iostream> #include <deque> using namespace std; int main() { deque<int> d = {2, 4, 6}; // Adding elements at both ends d.push_front(1); d.push_back(7); // Accessing elements cout << "Elements: "; for (int x : d) { cout << x << " "; } cout << endl; // Removing elements from both ends d.pop_front(); d.pop_back(); cout << "After pop_front and pop_back: "; for (int x : d) { cout << x << " "; } cout << endl; return 0; }
Output:
Elements: 1 2 4 6 7 After pop_front and pop_back: 2 4 6
3. Associative Containers: set
A set is a container that stores unique elements in a sorted order.
Example: Basic Operations with set
#include <iostream> #include <set> using namespace std; int main() { set<int> s = {3, 1, 4, 2, 5}; // Adding elements s.insert(6); // Displaying elements (sorted automatically) cout << "Elements: "; for (int x : s) { cout << x << " "; } cout << endl; // Removing an element s.erase(4); cout << "After erase(4): "; for (int x : s) { cout << x << " "; } cout << endl; return 0; }
Output:
Elements: 1 2 3 4 5 6 After erase(4): 1 2 3 5 6
4. Associative Containers: map
A map is an associative container that stores key-value pairs with unique keys in sorted order.
Example: Basic Operations with map
#include <iostream> #include <map> using namespace std; int main() { map<string, int> age; // Inserting key-value pairs age["Alice"] = 25; age["Bob"] = 30; age["Charlie"] = 28; // Accessing elements cout << "Bob's age: " << age["Bob"] << endl; // Iterating through map cout << "All ages:" << endl; for (const auto& pair : age) { cout << pair.first << " is " << pair.second << " years old." << endl; } return 0; }
Output:
Bob's age: 30 All ages: Alice is 25 years old. Bob is 30 years old. Charlie is 28 years old.
5. Container Adaptors: stack
A stack is a container adaptor that allows access to elements in a Last-In-First-Out (LIFO) manner.
Example: Basic Operations with stack
#include <iostream> #include <stack> using namespace std; int main() { stack<int> s; // Pushing elements onto the stack s.push(1); s.push(2); s.push(3); cout << "Top element: " << s.top() << endl; // Popping elements from the stack s.pop(); cout << "After pop, top element: " << s.top() << endl; return 0; }
Output:
Top element: 3 After pop, top element: 2
6. Container Adaptors: queue
A queue is a container adaptor that operates in a First-In-First-Out (FIFO) manner.
Example: Basic Operations with queue
#include <iostream> #include <queue> using namespace std; int main() { queue<int> q; // Adding elements to the queue q.push(1); q.push(2); q.push(3); cout << "Front element: " << q.front() << endl; // Removing elements from the queue q.pop(); cout << "After pop, front element: " << q.front() << endl; return 0; }
Output:
Front element: 1 After pop, front element: 2
7. Algorithms: sort
The sort algorithm sorts elements in a range in ascending order by default.
Example: Sorting a Vector
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> numbers = {4, 2, 3, 1, 5}; // Sorting in ascending order sort(numbers.begin(), numbers.end()); cout << "Sorted numbers: "; for (int num : numbers) { cout << num << " "; } cout << endl; return 0; }
Output:
Sorted numbers: 1 2 3 4 5
8. Algorithms: find
The find algorithm searches for an element in a range and returns an iterator to the first occurrence.
Example: Finding an Element in a Vector
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 5}; // Searching for 3 auto it = find(numbers.begin(), numbers.end(), 3); if (it != numbers.end()) { cout << "Found 3 at position " << distance(numbers.begin(), it) << endl; } else { cout << "3 not found" << endl; } return 0; }
Output:
Found 3 at position 2
9. Iterators: Traversing Containers
Iterators are used to traverse elements in containers. They provide flexibility for accessing elements in a container without exposing the internal structure.
Example: Using Iterators with vector
#include <iostream> #include <vector> using namespace std; int main() { vector<int> numbers = {10, 20, 30, 40, 50}; cout << "Elements: "; for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) { cout << *it << " "; } cout << endl; return 0; }
Output:
Elements: 10 20 30 40 50
10. Using Reverse Iterators
Reverse iterators allow traversing containers in reverse order.
Example: Using Reverse Iterators with vector
#include <iostream> #include <vector> using namespace std; int main() { vector<int> numbers = {1, 2, 3, 4, 5}; cout << "Elements in reverse order: "; for (auto it = numbers.rbegin(); it != numbers.rend(); ++it) { cout << *it << " "; } cout << endl; return 0; }
Output:
Elements in reverse order: 5 4 3 2 1
Summary Table
Component | Example | Description |
---|---|---|
vector | vector<int> v = {1, 2, 3}; | Dynamic array with random access |
deque | deque<int> d = {1, 2, 3}; | Double-ended queue, fast insert/delete at ends |
set | set<int> s = {1, 2, 3}; | Stores unique, sorted elements |
map | map<string, int> m; m[“key”] = value; | Key-value pairs, unique keys |
stack | stack<int> s; s.push(1); | LIFO container adaptor |
queue | queue<int> q; q.push(1); | FIFO container adaptor |
sort | sort(v.begin(), v.end()); | Sorts elements in a range |
find | find(v.begin(), v.end(), 3); | Finds first occurrence of an element |
Iterator | for (auto it = v.begin(); it != v.end(); ++it) | Traverses container using an iterator |
Reverse Iterator | for (auto it = v.rbegin(); it != v.rend(); ++it) | Traverses contain |
Complete Example
This example demonstrates the use of vector
, map
, sort
, and iterators.
#include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; int main() { vector<int> numbers = {5, 3, 9, 1, 4}; map<string, int> ages = {{"Alice", 25}, {"Bob", 30}, {"Carol", 22}}; // Sorting numbers sort(numbers.begin(), numbers.end()); cout << "Sorted numbers: "; for (int num : numbers) { cout << num << " "; } cout << endl; // Displaying map using iterator cout << "Ages:" << endl; for (auto it = ages.begin(); it != ages.end(); ++it) { cout << it->first << ": " << it->second << " years old" << endl; } return 0; }
Sample Output:
Sorted numbers: 1 3 4 5 9 Ages: Alice: 25 years old Bob: 30 years old Carol: 22 years old
Key Takeaways
- Containers: Provide various data structures for organizing data.
- Algorithms: Provide powerful functions for searching, sorting, counting, and more.
- Iterators: Allow efficient and flexible traversal of containers.