Skip to content
C++ Better Explained
Go back
C++ std::set Tutorial: Sorted Unique Collections for Beginners
Edit page

C++ std::set Tutorial: Sorted Unique Collections

Sometimes you need a collection where every element appears exactly once and you always want them in sorted order. That’s exactly what std::set is for. It handles both automatically — no manual sorting, no duplicate removal needed.


What Is std::set?

std::set is a container in the C++ Standard Library that:

The header you need is <set>.

#include <iostream>
#include <set>

int main() {
    std::set<int> numbers;
    numbers.insert(5);
    numbers.insert(2);
    numbers.insert(8);
    numbers.insert(2); // duplicate — ignored

    for (int n : numbers) {
        std::cout << n << " "; // prints: 2 5 8
    }
    std::cout << "\n";
    return 0;
}

Notice the output is sorted even though we inserted 5 first. The set maintains order for you.


Creating and Initializing a Set

You can initialize a set from a list of values, just like a vector:

#include <iostream>
#include <set>

int main() {
    std::set<std::string> fruits = {"banana", "apple", "cherry", "apple"};

    for (const std::string& f : fruits) {
        std::cout << f << "\n";
        // apple
        // banana
        // cherry
        // (apple duplicate was dropped, sorted alphabetically)
    }
    return 0;
}

Adding and Removing Elements

insert() adds an element. If it’s already in the set, nothing happens.

erase() removes an element by value. If the element doesn’t exist, nothing happens.

#include <iostream>
#include <set>

int main() {
    std::set<int> s = {10, 20, 30};

    s.insert(25);   // adds 25
    s.insert(10);   // already there — ignored
    s.erase(20);    // removes 20

    for (int n : s) {
        std::cout << n << " "; // prints: 10 25 30
    }
    std::cout << "\n";
    return 0;
}
If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

Checking If an Element Exists

Use count() for a simple yes/no check — for a set, it returns either 0 or 1:

std::set<int> s = {1, 2, 3, 4, 5};

if (s.count(3)) {
    std::cout << "3 is in the set\n";
}

if (!s.count(9)) {
    std::cout << "9 is NOT in the set\n";
}

You can also use find(), which returns an iterator. If the element isn’t found, it returns s.end():

auto it = s.find(3);
if (it != s.end()) {
    std::cout << "Found: " << *it << "\n";
}

Iterating Over a Set

A range-based for loop works perfectly with sets:

std::set<std::string> words = {"zebra", "ant", "monkey"};
for (const std::string& w : words) {
    std::cout << w << "\n"; // ant, monkey, zebra (sorted)
}

You can also iterate with iterators for more control:

for (auto it = words.begin(); it != words.end(); ++it) {
    std::cout << *it << "\n";
}

Useful Set Methods at a Glance

std::set<int> s = {1, 2, 3, 4, 5};

s.size();       // number of elements: 5
s.empty();      // false
s.clear();      // removes all elements
s.count(3);     // 1 if exists, 0 if not
s.find(3);      // iterator to element, or s.end()
s.insert(6);    // add element
s.erase(1);     // remove element by value

Set vs Vector: When to Use Which

Featurestd::vectorstd::set
Preserves insertion orderYesNo (always sorted)
Allows duplicatesYesNo
Index access (v[i])YesNo
Lookup speedO(n) linearO(log n) fast
Sorted automaticallyNoYes

Use a vector when you need to preserve order, allow duplicates, or access elements by index.

Use a set when you need unique elements, automatic sorting, or fast membership testing.


Practical Example: Removing Duplicates from a Vector

A common use of set is deduplicating a vector:

#include <iostream>
#include <vector>
#include <set>

int main() {
    std::vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};

    // Insert all elements into a set to deduplicate
    std::set<int> unique(nums.begin(), nums.end());

    std::cout << "Unique sorted values:\n";
    for (int n : unique) {
        std::cout << n << " "; // 1 2 3 4 5 6 9
    }
    std::cout << "\n";
    return 0;
}

What About std::unordered_set?

If you don’t need elements sorted — you just want fast duplicate checking — use std::unordered_set from <unordered_set>. It’s O(1) average for insert and lookup instead of O(log n), but the order is unpredictable.

#include <unordered_set>
std::unordered_set<int> fast = {5, 2, 8};
fast.insert(2); // still ignored — duplicates not allowed

Use std::set when order matters or when you need consistent iteration order. Use std::unordered_set when raw speed matters more.



Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Edit page
Share this post on:

Previous Post
C++ Queue and Stack Tutorial: FIFO and LIFO Containers Explained
Next Post
How to Convert String to int in C++: stoi, atoi, and stringstream