Skip to content
C++ Better Explained
Go back
C++ Sort Vector of Structs: By Field with std::sort
Edit page

C++ Sort Vector of Structs: By Field with std::sort

To sort a vector of structs in C++, pass std::sort a lambda that compares the field you care about: std::sort(v.begin(), v.end(), [](const auto& a, const auto& b){ return a.field < b.field; }). The lambda tells sort which element should come first.


The Setup

Say we have a struct for people and a vector of them:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

struct Person {
    std::string name;
    int age;
};

int main() {
    std::vector<Person> people = {
        {"Alice", 30}, {"Bob", 25}, {"Carol", 35}
    };
    // sorting comes next
    return 0;
}

By default std::sort has no idea how to order a Person — there’s no built-in rule for “less than” on a struct. We supply that rule with a comparator.


Sort by a Single Field

A lambda comparator takes two elements and returns true if the first should come before the second:

std::sort(people.begin(), people.end(),
    [](const Person& a, const Person& b) {
        return a.age < b.age;   // youngest first
    });

for (const Person& p : people)
    std::cout << p.name << " (" << p.age << ")\n";
// Bob (25), Alice (30), Carol (35)

Reading a.age < b.age as “a comes before b when a is younger” makes ascending order. To sort by name instead, just compare a.name < b.namestd::string already knows alphabetical order.

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.

Descending Order

To reverse the order, flip the comparison operator:

std::sort(people.begin(), people.end(),
    [](const Person& a, const Person& b) {
        return a.age > b.age;   // oldest first
    });

Using > instead of < puts larger values first. That single character is the only difference between ascending and descending.


Sort by Multiple Fields

To sort by age, then break ties by name, compare the second field only when the first is equal. The clean way is std::tie, which compares fields in order:

#include <tuple>

std::sort(people.begin(), people.end(),
    [](const Person& a, const Person& b) {
        return std::tie(a.age, a.name) < std::tie(b.age, b.name);
    });

std::tie groups the fields into a tuple, and tuples compare left to right: first by age, and only if ages match, by name. This scales to as many fields as you like without nested if statements.


Tip: Define operator< for a Natural Order

If a struct has one obvious default ordering, define operator< on it. Then plain std::sort(v.begin(), v.end()) works with no comparator:

struct Person {
    std::string name;
    int age;
    bool operator<(const Person& other) const {
        return age < other.age;
    }
};

This is handy when you’ll sort the same way repeatedly, but a lambda is more flexible when you sort by different fields in different places.



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++ Remove Element from Vector (and Remove Duplicates)
Next Post
C++ Split String: How to Split a String by Delimiter (3 Ways)