cpp_034: Map in C++
In C++, a map is a built-in container in the Standard Template Library (STL). It is used to store key-value pairs, where:
- Each key is unique.
- Each key is mapped to a value.
- The keys are automatically sorted in ascending order (by default).
Think of it like a dictionary in Python!
Below, each main function of the map in C++ is listed along with a standalone example. Each example includes the code, its output, and a clear explanation to help you understand the specific function.
1. insert() — Add a Key-Value Pair
The insert function adds a key-value pair to the map. If the key exists, the insertion is ignored. Multiple insertion methods exist, with varying efficiency.
Example: Different Insertion Methods
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students;
// Different insertion methods
students.insert({1, "Alice"}); // Initializer list
students.emplace(2, "Bob"); // In-place construction
students.insert(make_pair(3, "Charlie")); // Using make_pair
students.insert(pair<int, string>(4, "Dave")); // Explicit pair
cout << "After insertions:" << endl;
for (const auto& pair : students) {
cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
}
return 0;
}Output:
After insertions:
ID: 1, Name: Alice
ID: 2, Name: Bob
ID: 3, Name: Charlie
ID: 4, Name: DaveExplanation:
- Initializer List ({key, value}): Concise and modern (C++11). Constructs the pair directly. Efficiency: Good, minimal copies.
- emplace: Constructs the pair in-place, avoiding temporary objects. Efficiency: Best, optimal for performance.
- make_pair: Creates a temporary std::pair for insertion. Efficiency: Slightly less efficient due to temporary object creation.
- Explicit pair (pair<Key, T>): Verbose, creates a temporary pair. Efficiency: Least efficient, not recommended.
- Recommendation: Use emplace for performance or initializer list for readability. Avoid explicit pair construction.
2. find(key) — Search for a Key
The find function searches for a key and returns an iterator to the key-value pair or end() if not found.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
int key = 2;
auto it = students.find(key);
if (it != students.end()) {
cout << "Found key " << key << ": " << it->second << endl;
} else {
cout << "Key " << key << " not found" << endl;
}
key = 5;
it = students.find(key);
if (it != students.end()) {
cout << "Found key " << key << ": " << it->second << endl;
} else {
cout << "Key " << key << " not found" << endl;
}
return 0;
}Output:
Found key 2: Bob
Key 5 not foundExplanation:
- find: Returns an iterator to the key-value pair if the key exists, or end() if it doesn’t.
- auto: Automatically infers the type of it. Here, it is a map<int, string>::iterator.
- find(key): Looks for the key in the map and returns an iterator to the matching element.
it != students.end(): =>
- students.end(): Points to the position past the map’s last element.
- The condition checks if it equals end(). If true, the key was not found.
it->second: =>
- Accesses the value of the key-value pair that the iterator points to.
- (it->first would access the key.)
3. erase(key) — Remove a Key-Value Pair
The erase function removes a key-value pair by key, iterator, or range.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
students.erase(2); // Erase by key
cout << "After erasing key 2:" << endl;
for (const auto& pair : students) {
cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
}
return 0;
}Output:
After erasing key 2:
ID: 1, Name: Alice
ID: 3, Name: CharlieExplanation:
- erase(key) removes the pair with the specified key.
4. size() — Get Number of Elements
The size function returns the number of key-value pairs in the map.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
cout << "Number of students: " << students.size() << endl;
students.emplace(4, "Dave");
cout << "Number of students after adding one: " << students.size() << endl;
return 0;
}Output:
Number of students: 3
Number of students after adding one: 4Explanation:
- size() returns the current number of elements.
5. empty() — Check if Map is Empty
The empty function returns true if the map is empty, false otherwise.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students;
cout << "Is map empty? " << (students.empty() ? "Yes" : "No") << endl;
students.emplace(1, "Alice");
cout << "Is map empty after adding an element? " << (students.empty() ? "Yes" : "No") << endl;
return 0;
}Output:
Is map empty? Yes
Is map empty after adding an element? NoExplanation:
- empty(): Checks if the map has no elements.
Return value:
- true: Map is empty.
- false: Map contains at least one element.
(students.empty() ? “Yes” : “No”):
A ternary operator, a concise if-else statement.
Get CodeAddict’s stories in your inbox
Join Medium for free to get updates from this writer.
General syntax=>(condition ? value_if_true : value_if_false)
- Condition: students.empty()
- If true: Returns “Yes” (map is empty).
- If false: Returns “No” (map has elements).
6. clear() — Remove All Elements
The clear function removes all key-value pairs, leaving the map empty.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
cout << "Before clear, size: " << students.size() << endl;
students.clear();
cout << "After clear, size: " << students.size() << endl;
cout << "Is map empty? " << (students.empty() ? "Yes" : "No") << endl;
return 0;
}Output:
Before clear, size: 3
After clear, size: 0
Is map empty? YesExplanation:
- clear() removes all elements, resetting the map.
7. count(key) — Check if a Key Exists
The count function returns 1 if the key exists, 0 otherwise (since std::map has unique keys).
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
cout << "Key 2 exists: " << (students.count(2) ? "Yes" : "No") << endl;
cout << "Key 5 exists: " << (students.count(5) ? "Yes" : "No") << endl;
return 0;
}Output:
Key 2 exists: Yes
Key 5 exists: NoExplanation:
- count(key) is a simple way to check key existence.
8. operator[] — Access or Insert Elements
The operator[] accesses a value by key. If the key doesn’t exist, it inserts a default-constructed value.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}};
cout << "Accessing key 1: " << students[1] << endl;
students[3] = "Charlie"; // Inserts key 3
cout << "After adding key 3:" << endl;
for (const auto& pair : students) {
cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
}
// Note: Accessing a non-existent key inserts it
string value = students[4]; // Inserts key 4 with empty string
cout << "After accessing key 4:" << endl;
for (const auto& pair : students) {
cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
}
return 0;
}Output:
Accessing key 1: Alice
After adding key 3:
ID: 1, Name: Alice
ID: 2, Name: Bob
ID: 3, Name: Charlie
After accessing key 4:
ID: 1, Name: Alice
ID: 2, Name: Bob
ID: 3, Name: Charlie
ID: 4, Name: Explanation:
- operator[] is convenient but can unintentionally insert elements.
- Use cautiously for read-only operations; prefer at or find.
9. at(key) — Access a Value
The at function accesses a value by key, throwing std::out_of_range if the key doesn’t exist.
Example
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}};
try {
cout << "Accessing key 1: " << students.at(1) << endl;
cout << "Accessing key 3: " << students.at(3) << endl; // Throws exception
} catch (const out_of_range& e) {
cout << "Error: " << e.what() << endl;
}
return 0;
}
Output:
Accessing key 1: Alice
Error: _Map_base::atExplanation:
- at(key) is safer than operator[] for read-only access, as it doesn’t modify the map.
- Introduced in C++11.
10. Looping Through a Map
You can iterate over a std::map using various methods. Below are examples of common approaches.
Example: Range-Based For Loop
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
cout << "Students (range-based for loop):" << endl;
for (const auto& pair : students) {
cout << "ID: " << pair.first << ", Name: " << pair.second << endl;
}
return 0;
}Output:
Students (range-based for loop):
ID: 1, Name: Alice
ID: 2, Name: Bob
ID: 3, Name: CharlieExample: Iterator-Based Loop
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
cout << "Students (iterator-based loop):" << endl;
for (auto it = students.begin(); it != students.end(); ++it) {
cout << "ID: " << it->first << ", Name: " << it->second << endl;
}
return 0;
}Example: Reverse Iteration
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
cout << "Students (reverse iteration):" << endl;
for (auto it = students.rbegin(); it != students.rend(); ++it) {
cout << "ID: " << it->first << ", Name: " << it->second << endl;
}
return 0;
}Explanation:
- Range-Based For Loop: Simplest and most readable (C++11+).
- Iterator-Based Loop: Offers more control, useful for complex operations.
- Reverse Iteration: Uses rbegin() and rend() for descending order.
- All methods access pair.first (key) and pair.second (value).
11. Other Important Functions
- begin() and end(): Iterators to the first and past-the-last elements.
- rbegin() and rend(): Reverse iterators for descending order.
- lower_bound(key): Iterator to the first element not less than key.
- upper_bound(key): Iterator to the first element greater than key.
- equal_range(key): Pair of iterators for the range of elements with key.
Happy Coding!!







