STL Containers
Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 71 of 104.
STL containers are template classes that store and organize collections of objects. Each container type is optimized for different access patterns and operations. Choosing the right container for your needs can significantly impact your program's performance.
Sequence containers maintain elements in a specific order:
#include <vector>
#include <list>
std::vector<int> vec = {1, 2, 3}; // Dynamic array, fast random access
vec.push_back(4); // Add to end: O(1) amortized
int x = vec[2]; // Access by index: O(1)
std::list<int> lst = {1, 2, 3}; // Doubly-linked list
lst.push_front(0); // Add to front: O(1)
lst.push_back(4); // Add to end: O(1)Associative containers store elements in sorted order for fast lookup:
#include <map>
#include <set>
std::set<int> s = {3, 1, 4, 1}; // Unique sorted elements: {1, 3, 4}
s.insert(2); // Insert: O(log n)
bool found = s.count(3); // Check existence: O(log n)
std::map<std::string, int> ages; // Key-value pairs, sorted by key
ages["Alice"] = 25; // Insert/update: O(log n)
ages["Bob"] = 30;
std::cout << ages["Alice"]; // Access: O(log n)Unordered containers use hash tables for even faster average-case lookup:
#include <unordered_map>
std::unordered_map<std::string, int> scores;
scores["player1"] = 100; // Insert: O(1) average
scores["player2"] = 200;
std::cout << scores["player1"]; // Access: O(1) averageUse vector when you need fast random access, list for frequent insertions in the middle, map/set when you need sorted data, and unordered_map when lookup speed is critical and order doesn't matter.
Challenge
EasyLet's build a student grade management system that demonstrates how different STL containers serve different purposes. You'll use multiple container types to organize student data efficiently, choosing the right container for each task.
You'll create two files to organize your code:
GradeManager.h: Define aGradeManagerclass that uses multiple STL containers to manage student information.Your class should use:
- A
std::vector<std::string>to store student names in the order they were added - A
std::map<std::string, int>to associate each student name with their grade - A
std::set<int>to track all unique grades that have been assigned
Implement these methods:
addStudent(const std::string& name, int grade)— adds a student with their grade to all three containersgetGrade(const std::string& name)— returns the grade for a given student name using the mapprintRoster()— prints all student names in the order they were added (from the vector), each on a new lineprintGrades()— prints all students with their grades in alphabetical order (the map handles this automatically), formatted asname: gradeon each lineprintUniqueGrades()— prints all unique grades in ascending order (the set handles this), separated by spaces followed by a newline
- A
main.cpp: Read inputs and demonstrate how each container type serves a different purpose.Read six inputs (each on a separate line):
- First student name
- First student grade (integer)
- Second student name
- Second student grade (integer)
- Third student name
- Third student grade (integer)
Create a
GradeManagerand add all three students. Then demonstrate the different container behaviors:- Print
Roster (insertion order):followed by callingprintRoster() - Print
Grades (alphabetical):followed by callingprintGrades() - Print
Unique grades:followed by callingprintUniqueGrades() - Look up the second student's grade and print
<name>'s grade: <grade>
For example, with inputs Charlie, 85, Alice, 90, Bob, 85:
Roster (insertion order):
Charlie
Alice
Bob
Grades (alphabetical):
Alice: 90
Bob: 85
Charlie: 85
Unique grades:
85 90
Alice's grade: 90Notice how the vector preserves insertion order (Charlie, Alice, Bob), the map automatically sorts by key (Alice, Bob, Charlie), and the set stores only unique values in sorted order (85 appears once, not twice). Each container type excels at different tasks!
Cheat sheet
STL containers are template classes for storing and organizing collections of objects. Each type is optimized for different operations.
Sequence Containers
Maintain elements in a specific order:
#include <vector>
#include <list>
std::vector<int> vec = {1, 2, 3}; // Dynamic array, fast random access
vec.push_back(4); // Add to end: O(1) amortized
int x = vec[2]; // Access by index: O(1)
std::list<int> lst = {1, 2, 3}; // Doubly-linked list
lst.push_front(0); // Add to front: O(1)
lst.push_back(4); // Add to end: O(1)Associative Containers
Store elements in sorted order for fast lookup:
#include <map>
#include <set>
std::set<int> s = {3, 1, 4, 1}; // Unique sorted elements: {1, 3, 4}
s.insert(2); // Insert: O(log n)
bool found = s.count(3); // Check existence: O(log n)
std::map<std::string, int> ages; // Key-value pairs, sorted by key
ages["Alice"] = 25; // Insert/update: O(log n)
ages["Bob"] = 30;
std::cout << ages["Alice"]; // Access: O(log n)Unordered Containers
Use hash tables for faster average-case lookup:
#include <unordered_map>
std::unordered_map<std::string, int> scores;
scores["player1"] = 100; // Insert: O(1) average
scores["player2"] = 200;
std::cout << scores["player1"]; // Access: O(1) averageChoosing the Right Container
vector: Fast random accesslist: Frequent insertions in the middlemap/set: Sorted data neededunordered_map: Lookup speed critical, order doesn't matter
Try it yourself
#include <iostream>
#include <string>
#include "GradeManager.h"
using namespace std;
int main() {
// Read inputs for three students
string name1, name2, name3;
int grade1, grade2, grade3;
cin >> name1;
cin >> grade1;
cin >> name2;
cin >> grade2;
cin >> name3;
cin >> grade3;
// TODO: Create a GradeManager object
// TODO: Add all three students to the GradeManager
// TODO: Print "Roster (insertion order):" and call printRoster()
// TODO: Print "Grades (alphabetical):" and call printGrades()
// TODO: Print "Unique grades:" and call printUniqueGrades()
// TODO: Look up the second student's grade and print "<name>'s grade: <grade>"
return 0;
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesC++ Build & CompilationHeader Files & Source FilesNamespaces & ScopeIntroduction to OOP in C++Classes vs ObjectsThe 'this' PointerMethods (Member Functions)Attributes (Data Members)Ctors & Dtors BasicsRecap - Simple Calculator4Class Properties
Instance vs Static MembersGetters and SettersConst Member FunctionsMutable KeywordStatic Methods and VariablesFriend Functions & ClassesRecap - Bank Account Manager7Inheritance
Basic InheritanceInheritance Access LevelsCtor & Dtor Call OrderMethod OverridingVirtual Functions & VTableMultiple InheritanceVirtual InheritanceRecap - Employee Hierarchy10STL Overview
STL Overview & PhilosophySTL ContainersIteratorsSTL AlgorithmsFunctors & Lambda ExpressionsRecap - Word Frequency2Memory Management
Stack vs Heap MemoryPointers and ReferencesDynamic Memory (new/delete)Smart Pointers in C++RAII in C++Recap - Dynamic Array Manager5Encapsulation
Access Specifiers in C++Access Specifiers In DepthInformation HidingStruct vs ClassNested & Inner ClassesRecap - Student Records System8Polymorphism
Compile vs Runtime PolymorphFunction OverloadingVirtual Functions RevisitedPure Virtual FunctionsAbstract ClassesInterface Design in C++Dynamic Casting & RTTIRecap - Shape Calculator3Constructors & Destructors
Default ConstructorParameterized ConstructorCopy ConstructorMove ConstructorConstructor Init ListsDelegating ConstructorsDestructor Deep DiveRule of Three / Five / ZeroRecap - String Class6Operator Overloading
Intro to Operator OverloadArithmetic Operator OverloadComparison Operator OverloadStream OperatorsAssignment Operator Overload[] and () Operator OverloadType Conversion OperatorsRecap - Matrix Class9Templates
Function TemplatesClass TemplatesTemplate SpecializationVariadic TemplatesSFINAE & Type Traits BasicsRecap - Generic Container