Beyond the Basics
Iterators, Algorithms & Lambdas
Walk any container with iterators, then use the STL algorithms — sort, find, count, binary_search, accumulate, transform — with lambda functions for custom behaviour.
Iterators
An iterator is an object that points to an element of a container and can move to the next one — a generalised pointer. begin() points to the first element; end() points one past the last.
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main() {
vector<int> v = {10, 20, 30, 40};
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
cout << *it << " "; // dereference like a pointer
cout << endl;
list<string> names = {"Asha", "Ravi", "Meera"};
for (auto it = names.rbegin(); it != names.rend(); ++it) // reverse iterators
cout << *it << " ";
cout << endl;
return 0;
}10 20 30 40 Meera Ravi Asha
Because every container offers iterators, one algorithm works on all of them.
Lambda expressions
A lambda is an unnamed function written inline: [capture](parameters) { body }. It is the easiest way to give an algorithm custom behaviour.
#include <iostream>
using namespace std;
int main() {
auto square = [](int x) { return x * x; };
int bonus = 5;
auto addBonus = [bonus](int m) { return m + bonus; }; // captures bonus by value
int calls = 0;
auto counter = [&calls]() { calls++; }; // captures calls by reference
counter(); counter(); counter();
cout << square(7) << " " << addBonus(80) << " " << calls << endl;
return 0;
}49 85 3
The essential algorithms
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <string>
using namespace std;
void show(const vector<int> &v) { for (int x : v) cout << x << " "; cout << endl; }
int main() {
vector<int> v = {42, 7, 19, 7, 88, 3, 25};
sort(v.begin(), v.end()); // ascending
cout << "sorted: "; show(v);
sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); // descending
cout << "descending: "; show(v);
cout << "max element: " << *max_element(v.begin(), v.end()) << endl;
cout << "sum: " << accumulate(v.begin(), v.end(), 0) << endl;
cout << "count of 7: " << count(v.begin(), v.end(), 7) << endl;
cout << "count > 20: " << count_if(v.begin(), v.end(), [](int x) { return x > 20; }) << endl;
auto it = find(v.begin(), v.end(), 19);
cout << "19 found at index " << (it - v.begin()) << endl;
sort(v.begin(), v.end());
cout << "binary_search 25: " << boolalpha << binary_search(v.begin(), v.end(), 25) << endl;
v.erase(unique(v.begin(), v.end()), v.end()); // remove adjacent duplicates
cout << "unique: "; show(v);
reverse(v.begin(), v.end());
cout << "reversed: "; show(v);
vector<int> doubled(v.size());
transform(v.begin(), v.end(), doubled.begin(), [](int x) { return 2 * x; });
cout << "doubled: "; show(doubled);
return 0;
}sorted: 3 7 7 19 25 42 88 descending: 88 42 25 19 7 7 3 max element: 88 sum: 191 count of 7: 2 count > 20: 3 19 found at index 3 binary_search 25: true unique: 3 7 19 25 42 88 reversed: 88 42 25 19 7 3 doubled: 176 84 50 38 14 6
Sorting objects
Pass a comparison lambda to sort by any field:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct Student { string name; int marks; };
int main() {
vector<Student> cls = {{"Asha", 88}, {"Ravi", 95}, {"Meera", 88}, {"Kiran", 72}};
stable_sort(cls.begin(), cls.end(), [](const Student &a, const Student &b) {
return a.marks > b.marks; // highest marks first; ties keep their order
});
int rank = 1;
for (const auto &s : cls) cout << rank++ << ". " << s.name << " " << s.marks << endl;
return 0;
}1. Ravi 95 2. Asha 88 3. Meera 88 4. Kiran 72
| Algorithm | Does | Cost |
|---|---|---|
sort |
sort a range (introsort) | O(n log n) |
stable_sort |
sort, keeping equal elements in order | O(n log n) |
find, find_if |
first match | O(n) |
count, count_if |
number of matches | O(n) |
binary_search, lower_bound |
search a sorted range | O(log n) |
accumulate (<numeric>) |
sum or fold | O(n) |
min_element, max_element |
position of the min / max | O(n) |
reverse, rotate, unique |
rearrange | O(n) |
transform |
apply a function to every element | O(n) |
Test yourself
4 questions · pick an answer to check it instantly
- 1
What does
v.end()point to?end()is a sentinel; dereferencing it is invalid. - 2
Which call sorts
vin descending order?The comparator returns true whenashould come beforeb. - 3
In
[&total](int x) { total += x; }, how istotalcaptured?&captures by reference, so the lambda can modify the original. - 4
What must be true before calling
binary_search?Binary search relies on order to halve the range.