Maps & Sets in C++
A std::map stores key-value pairs so you can look up a value by a meaningful key, and a std::set stores a collection of unique values with fast membership tests. Where a vector finds things by position, maps and sets find things by content. Reach for a map when you want "given this name, what is the score?" and a set when you want "have I seen this value before?"
Here is each, with the ordered and unordered variants.
std::map — key-value lookups
Include <map>. A map keeps its keys sorted and stores one value per key.
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, int> scores;
scores["Asha"] = 95; // insert or update
scores["Ravi"] = 72;
scores["Meera"] = 88;
std::cout << "Asha: " << scores["Asha"] << "\n"; // 95
// iterate in sorted key order
for (const auto& [name, score] : scores) {
std::cout << name << " -> " << score << "\n";
}
}
Output (keys come out sorted):
Asha: 95
Asha -> 95
Meera -> 88
Ravi -> 72
The structured binding const auto& [name, score] cleanly unpacks each pair.
Looking up safely
scores["Unknown"] has a surprising side effect: if the key is missing, it inserts it with a default value (0 for int). To check without inserting, use find or contains.
#include <map>
#include <string>
#include <iostream>
int main() {
std::map<std::string, int> scores{{"Asha", 95}};
// C++20: contains() — does not insert
if (scores.contains("Ravi")) {
std::cout << "Ravi found\n";
} else {
std::cout << "Ravi not found\n";
}
// find() returns an iterator; end() means "not present"
if (auto it = scores.find("Asha"); it != scores.end()) {
std::cout << it->first << " = " << it->second << "\n";
}
}
std::set — unique values
Include <set>. A set stores each value at most once, sorted, and answers "is this here?" quickly.
#include <iostream>
#include <set>
int main() {
std::set<int> seen;
seen.insert(5);
seen.insert(2);
seen.insert(5); // duplicate ignored
std::cout << "size: " << seen.size() << "\n"; // 2
std::cout << "has 2? " << seen.contains(2) << "\n"; // 1 (true)
for (int v : seen) { // iterates in sorted order: 2 5
std::cout << v << " ";
}
std::cout << "\n";
}
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesOrdered vs unordered
std::map / std::set keep keys sorted (logarithmic-time operations, backed by a balanced tree). Their cousins std::unordered_map / std::unordered_set use hashing for average constant-time lookups but no ordering.
- Need elements in sorted order, or range queries? Use
std::map/std::set. - Just need fast lookup and do not care about order? Use
std::unordered_map/std::unordered_set.
A practical pattern: counting frequencies
A map shines when you need to count how often each thing appears — words in a sentence, marks in a class, votes in a poll. The default-insert behaviour of [] actually helps here, because a missing key starts at 0 and is then incremented.
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, int> wordCount;
for (const std::string& word : {"a", "b", "a", "c", "b", "a"}) {
++wordCount[word]; // missing keys start at 0, then increment
}
for (const auto& [word, count] : wordCount) {
std::cout << word << ": " << count << "\n";
}
}
Output (sorted by key):
a: 3
b: 2
c: 1
The same pattern with std::unordered_map runs faster on large inputs but prints the words in no particular order. Choose based on whether you need the sorted output.
Common mistakes
- Using
[]to check if a key exists.m["x"]inserts"x"if it is missing. Usecontains()orfind()for a pure lookup. - Expecting
unordered_mapto be sorted. It is not — only the orderedmap/setkeep keys in order. - Inserting duplicate keys into a map.
m["k"] = 1; m["k"] = 2;keeps only the last value; maps store one value per key. - Dereferencing the result of
find()without checking. Compare againstend()first; it signals "not found."
FAQ
When should I use a map versus a vector? Use a map when you look things up by a key (a name, an ID). Use a vector when you access by position or just need an ordered list.
What is the difference between map and unordered_map?
map keeps keys sorted and offers logarithmic-time operations; unordered_map uses hashing for average constant-time lookups but does not keep any order.
Keep learning
- See how these containers fit the bigger picture in The C++ STL Explained.
- For position-based collections, see Vectors in C++.
- Browse the full series on the C++ OOP hub.
Build real programs with the STL alongside mentors in Jalgaon — join the waitlist for our C++ Programming course.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesFounder, Infoplanet
Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.
Related guides
Classes & Objects in C++
Understand C++ classes and objects — defining a class, creating objects, member functions, and access control with public and private members.
Constructors & Destructors in C++
Understand C++ constructors and destructors — how objects are initialised and cleaned up, including parameterised, copy constructors, and initializer lists.
Encapsulation & Abstraction in C++
Understand encapsulation and abstraction in C++ — hiding internal data, exposing controlled interfaces, and why both make code safer and easier to change.
