Stl

By the end of this lesson you'll be able to pick the right STL container for any job — vector , string , map / unordered_map , set / unordered_set , pair — and insert, look up, and iterate over each one with iterators and range-for.

Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn

💡 Real-World Analogy

The STL is a professional toolbox . You don't whittle your own hammer — you reach for the right tool. A vector is a numbered shelf you can add to. A map is a dictionary : look up a word (the key) to get its definition (the value). A set is a guest list where each name appears once. A pair is a luggage tag tying a name to a number. Picking the wrong container is like using a wrench to hammer a nail — it works badly. This lesson is about choosing the right tool.

📦 The Core Containers

Container

Holds

Analogy

Reach for it when…

vector < T >

Ordered list of T

Numbered shelf

You want a resizable array (the default choice)

string

Text

Sentence

You're working with characters/words

map < K,V >

Sorted key→value

Dictionary

You look things up by key AND want sorted keys

unordered_map < K,V >

Hashed key→value

Hash table

You want the fastest lookups, order doesn't matter

set < T >

Unique, sorted

Sorted guest list

No duplicates allowed and you want them sorted

pair < A,B >

Two values

Luggage tag

You need to return/keep two things as one

1. std::vector — the resizable array

A vector is a list that grows and shrinks automatically, so it's the container you reach for 90% of the time. You add to the end with push_back , read any item by position with [] (indexes start at 0 ), and walk through it with a range-for. To insert or erase in the middle you give a position — an iterator like begin() + 1 . Read this worked example, run it, then you'll write one.

Your turn. The program below is almost complete — fill in the two blanks marked ___ using the hints, then run it.

2. std::map & std::unordered_map — key → value

A map stores key → value pairs, like a dictionary where you look up a word to get its meaning. std::map < K,V > keeps keys sorted (lookups cost O(log n)); std::unordered_map has the same interface but hashes keys for O(1) average lookups with no order. The big gotcha: myMap[key] inserts a default value when the key is missing, so to merely check a key use .count() or .find() — they never insert.

Now you try. Build a tiny phone book and check a key safely — fill in the two blanks:

3. std::set , std::pair & iterators

A set holds unique values — try to add a duplicate and it's silently ignored — and std::set keeps them sorted ( std::unordered_set is the hash-based, unordered twin). A pair glues two values into one object you reach with .first and .second . Underneath every container are iterators : begin() points at the first element, end() points one past the last (a stop sign, not a value), and *it reads what the iterator points at. auto spares you from spelling out the iterator's type.

🔎 Deep Dive: ordered vs unordered cost

The map / set pair are built on balanced trees : every insert, erase, and lookup costs O(log n) , and you get sorted order for free. The unordered_ pair use a hash table : O(1) average , but the elements come out in no useful order.

Rule of thumb: if you need the keys sorted (printing alphabetically, range queries), use the ordered version. If you just need fast membership tests or lookups and don't care about order, the unordered version is usually faster.

Pro Tips

Common Errors (and the fix)

📋 Quick Reference — which container?

You need…

Use

Insert

Lookup

An ordered, resizable list

v.push_back(x)

v[i]

Key → value, sorted keys

m[k] = v

m.find(k)

Key → value, fastest

m.count(k)

Unique items, sorted

s.insert(x)

s.count(x)

Unique items, fastest

unordered_set < T >

Two values as one

{a, b}

p.first / p.second

Frequently Asked Questions

Mini-Challenge: Word Frequency Counter

No blanks this time — just a brief and an outline. Count how many times each word appears using a map < string,int > , then print the tallies. Because std::map sorts keys, your output comes out alphabetically for free. Build it, run it, and check against the expected output.

🎉 Lesson Complete

Practice quiz

Which container is the default 'resizable list' you reach for most often?

  • std::map
  • std::set
  • std::vector
  • std::pair

Answer: std::vector. std::vector is a contiguous, cache-friendly resizable array — the everyday default container.

How do you add an element to the end of a std::vector?

  • v.push_back(x)
  • v.append(x)
  • v.insert(x)
  • v.add(x)

Answer: v.push_back(x). push_back appends to the end of a vector.

What does std::map store, and what order are its keys in?

  • Unique values, no order
  • Key to value pairs in insertion order
  • A single value per index
  • Key to value pairs, with keys kept sorted (O(log n))

Answer: Key to value pairs, with keys kept sorted (O(log n)). std::map stores key to value pairs in sorted key order using a balanced tree, costing O(log n) per operation.

What is the gotcha with using myMap[key] to look up a key?

  • It is slower than .find()

operator[] inserts a default value for a missing key, so to merely check use .count() or .find().

Which method checks whether a key exists in a map WITHOUT inserting it?

  • map.count(key) or map.find(key)

Answer: map.count(key) or map.find(key). count() and find() never insert; [] would create the key. Use them to test existence.

What is the main difference between std::map and std::unordered_map?

  • unordered_map cannot store strings
  • map is faster for all operations
  • map is a sorted tree (O(log n)); unordered_map is a hash table (O(1) average) with no order
  • unordered_map keeps keys sorted

Answer: map is a sorted tree (O(log n)); unordered_map is a hash table (O(1) average) with no order. map keeps keys sorted at O(log n); unordered_map hashes keys for O(1) average lookups but no ordering.

What happens when you insert a duplicate value into a std::set?

  • It is stored twice
  • It is silently ignored — sets hold only unique values
  • It throws an exception
  • It overwrites the existing one

Answer: It is silently ignored — sets hold only unique values. A set holds unique values; adding a duplicate is silently dropped.

What does end() point to in an STL container?

  • The last element
  • The first element
  • A null pointer
  • One past the last element — a stop sign, never dereference it

Answer: One past the last element — a stop sign, never dereference it. begin() is the first element but end() is one past the last; dereferencing end() is undefined behavior.

How do you read the value an iterator it points to?

  • it.value
  • *it
  • it->value()
  • &it

Answer: *it. Dereference the iterator with *it to read the element it points at.

Why might counting words with counts[word]++; work even for a brand-new word?

  • It throws and is caught
  • It inserts the word twice
  • A missing key is default-constructed to 0, so ++ makes it 1
  • It only works after calling .insert()

Answer: A missing key is default-constructed to 0, so ++ makes it 1. operator[] on a missing key creates it with value 0, so ++ immediately bumps it to 1 — a clean tally one-liner.

Continue this course