I'm AlanWu. When I started C++, my answer to "I need to store multiple things" was always an array. int arr[1000]. Every time.
Then I discovered the STL containers and realized I'd been working way too hard. Here's when to use what.
vector — your new default
If you used to write int arr[1000], use vector<int> arr instead. It grows, it shrinks, it knows its own size, and you can pass it to functions without also passing the length separately.
// Old way
int scores[100];
int n = 0;
scores[n++] = 95; // hope n doesn't exceed 99
// New way
vector<int> scores;
scores.push_back(95); // never overflow, never count manually
Use vector when: you need a list of things, in order, and you mainly add to the end or access by index.
Don't use vector when: you need to frequently insert or delete from the middle. That's O(n) — every element after shifts.
map — when you need to look stuff up by name
Arrays and vectors use integer indices. What if you want to look up a student's score by their name, not by number?
map<string, int> scores;
scores["Alice"] = 95;
scores["Bob"] = 88;
cout << scores["Alice"]; // 95
Under the hood, map is a balanced binary search tree. Lookup is O(log n), not O(1). But for most things, it's fast enough and the code is dead simple.
Use map when: you have key-value pairs and keys are not just 0, 1, 2, 3...
Don't use map when: you only need integer indices — that's what vector is for. Or when you need O(1) average lookup — then use unordered_map.
unordered_map — same thing, but faster (usually)
unordered_map<string, int> scores;
scores["Alice"] = 95;
Looks identical to map. The difference: unordered_map uses a hash table. Average lookup is O(1) instead of O(log n). But worst case is O(n) if there are collisions, keys have no order, and it uses more memory.
My rule: start with unordered_map. If you need keys in sorted order, switch to map.
set — when you only care if something exists
Need to track which IDs you've seen? Don't use a vector and loop through it every time.
set<int> seen;
seen.insert(42);
seen.insert(17);
if (seen.count(42)) { // true — O(log n)
// already seen it
}
set stores unique values in sorted order. No duplicates allowed.
For O(1) average and no ordering needed: unordered_set.
The actual decision tree
- Do you access by position (0, 1, 2...)? → vector.
- Do you need to look up by something that isn't a number? → unordered_map.
- Do those keys need to be sorted? → map.
- Do you only care "have I seen this before"? → unordered_set.
- Do you need those values in order or without duplicates? → set.
That covers 90% of cases.
The one you probably don't need: deque
I see beginners use deque because it sounds cool. Double-ended queue. Insert at both ends.
Unless you're writing a sliding window algorithm or a scheduler, you don't need deque. vector with push_back is faster and simpler.
Bottom line
Next time you reach for a plain array, ask: could a vector, map, or set do this in half the code? The answer is usually yes.
My GitHub: https://github.com/Cn-Alanwu
Top comments (0)