C++ Lambda Expressions and STL Algorithms
Learn C++ lambda expressions and STL algorithms with simple find, count_if and transform examples, clear capture rules and safe output storage.
What you will learn
- Read the parts of a small lambda expression.
- Use find and check its end result.
- Count matching values with count_if.
- Transform values into real output storage.
- Choose a safe value capture for a local rule.
An algorithm names a job you already know
You already know how to walk through a vector with a loop. You can search for a value, count values that pass a test, or build another sequence. The standard library supplies named algorithms for many of these jobs. Using one can make your intention easier to read. Instead of asking the reader to inspect a whole loop, count_if says that the job is to count matches.
STL is a common name used when talking about standard containers, iterators and algorithms. You do not need to learn a large new system to begin. Start with one algorithm, a small vector and a clear question. A range written with begin and end means start here and stop before this boundary. The end iterator is not an element. It must not be read as though it holds another number.
Some algorithms need a rule that your program supplies. A predicate is simply a rule that returns true or false. For example, is this number greater than five? A lambda expression is a compact way to write such a rule near the place it is used. A regular named function can work too. Choose the form that makes a small task easy to understand, not the form with the fewest characters.

Read a lambda like a small function
The brackets are the capture list, the parentheses hold the parameter, and the braces hold the work.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
true
false
After editing inputs, calculate a new prediction; this reference describes only the starter.
Read brackets, input and result one part at a time
In the first example, [] means the lambda does not take any outside local variables with it. (int value) says it receives one integer when called. The body returns whether the remainder after division by two is zero. isEven is a local name for this callable object. auto lets the compiler name its special type for us. Calling isEven(4) works much like calling an ordinary function.
The expression value % 2 == 0 returns a bool. Four passes the test, while seven does not. boolalpha asks the output stream to display true and false rather than one and zero. Nothing in this lambda changes the original number. A small read-only rule is a useful place to begin because its result depends only on its input and is easy to check by hand.
Do not confuse declaring the lambda with calling it. The declaration creates the callable object, but the body runs when it is called. The parameter name is local to that call. If a rule is used in several places or needs a long explanation, give it a clear name or write a regular function. A lambda is a tool for keeping a short rule close to its use, not permission to hide a complicated program inside one line.
- [] takes no outside local state.
- (int value) receives one number.
- The body checks the remainder and returns true or false.
- isEven(4) calls the rule and produces true.
Search, count and build a result
The destination vector has four existing elements before transform writes to it.
Predict the output, edit the source, then select Run code.
Compare with the starter's expected output
Found: 4
Matches: 2
Doubled: 4 14 8 18
After editing inputs, calculate a new prediction; this reference describes only the starter.
Check what each algorithm changes
find returns an iterator to the first matching element, or end when no match exists. The check before *found is required because end is not a stored value. find does a straightforward search through the sequence. It does not require sorting first. Try searching for eight instead of four and decide what your program should print when the result is missing. A missing value is a normal possible result, not automatically a program failure.
count_if applies the predicate to the input values and returns how many pass. In our vector, seven and nine are greater than five, so the count is two. It does not remove two or four. It does not put the matching values into another vector. Read the algorithm's name and contract carefully: counting, selecting and removing are different tasks even when they use the same true-or-false rule.
transform applies its rule to each input and writes results to the output positions. doubled(values.size()) creates enough real elements. reserve alone would only arrange capacity; it would not create elements to write through begin. Another valid approach is back_inserter with the proper header, but this lesson uses a sized destination first. Keep the input and output separate while learning, and check the size before running an algorithm that writes through iterators.
Repair a missing capture
Intentional compile error: limit is an outside local variable. Change [] to [limit] so the rule keeps a value copy.
Predict the output, edit the source, then select Run code.
Capture means what the rule keeps from outside
A lambda can use outside local data when its capture list allows it. [limit] stores a value copy of limit in the callable object. [&limit] refers to the existing local variable instead. The difference is similar to copying a value versus borrowing it in the pointer lesson. A reference capture must not be used after the referred-to local object is destroyed. A convenient short spelling does not remove the lifetime rule.
Repair the broken example with [limit]. The local rule then has its own copied threshold, and calling it with seven gives true. If the original mutable limit later changes, the stored copy does not automatically change with it. That is often what you want for one fixed calculation. For beginners, an explicit named value capture is easier to review than a broad default capture that quietly takes many outside variables.
Avoid making a predicate depend on a changing counter or on the order in which the algorithm happens to call it. Write a rule that answers the same question for the same input during the calculation. Also remember that algorithms may copy callable objects. A hidden mutable counter inside one copy is not a reliable way to count all visits. Use count_if for counting and keep the test itself focused on the value being tested.
Count above a limit and double the data
Read a count from zero through six, then that many readings between minus fifty and fifty, then one threshold in that same range. Every required number uses a complete input line. Validate everything before reporting. Use count_if with an explicit value capture of the threshold. A reading must be strictly greater than the threshold to count; a reading equal to it does not pass.
Create an output vector with the same size as the readings, then use transform to double each value. These bounds keep every result between minus one hundred and one hundred, so there is no integer overflow in this task. Print Above followed by the count, then Doubled followed by the new sequence in its original order. An empty input sequence gives Above: 0 and an empty Doubled row, but still requires the threshold line.
Test equal-to-threshold values, repeated values, negative readings, zero and both allowed endpoints. Reject suffixes, overflow and missing lines as Invalid input with status one. Keep the source vector unchanged and confirm the doubled vector has exactly the original number of elements. Explain why a count is not a filtered vector, and why having capacity is not the same as having writable elements. These two distinctions prevent common first mistakes.
Run the same program on your computer
Save one complete example as main.cpp. Choose your installed compiler and run only after a successful build. These are terminal commands, not C++ source. The in-page Run button needs the configured compiler sandbox.
macOS / Linux:
clang++ -std=c++20 -Wall -Wextra -Wpedantic main.cpp -o lesson
# Or use g++ with the same options.
./lesson
Windows Developer Command Prompt:
cl /std:c++20 /EHsc /W4 main.cpp /Fe:lesson.exe
lesson.exeIndependent lab
Use a captured threshold to count readings, then build a doubled result without changing the input.
Acceptance checklist
- Read count 0..6, that many readings -50..50, then a threshold -50..50 on whole lines.
- Reject bad required input as Invalid input with status 1 before any report.
- Use count_if with an explicit value capture and strict greater-than comparison.
- Use transform with a destination sized to the input; leave input unchanged.
- Print Above and Doubled, including empty data and bounded arithmetic.
Need a hint?
- Collect the threshold after the readings, even when the count is zero.
- Use [threshold](int value) for the counting rule.
- std::vector<int> doubled(values.size()) creates actual output elements.
Write and run your lab
Build your own solution before revealing the reference. Use the input field for normal, boundary and invalid cases; this runner executes your program but does not grade it.
Predict the output, edit the source, then select Run code.
Your lab evidence and notes
Record predictions, actual output, commands and the cause of each repair. Code is plain text: this scratchpad does not execute or grade C++.
Loading local notes…
Review your acceptance checklist and quiz explanations before marking this lesson complete. This is self-review, not a grade or certification.
Reveal the explained lab solution
Reference lab solution
Compare the reference with your own reasoning. Running this solution does not grade or complete the lesson.
Predict the output, edit the source, then select Run code.
Expected output
Above: 2
Doubled: -4 0 10 10
The threshold is captured by value, so the predicate reads one fixed copied rule during counting.
The sized output vector gives transform one valid output position per input value. reserve alone would not provide these elements.
The input range is small and bounded. Negative values, duplicates and an empty range have defined results without special unsafe indexing.
Review before moving on
Explain the lesson's objectives in your own words, compare your lab evidence with the acceptance checklist, and keep the first failing case alongside your repair. Completing a page is not proof that every C++ feature or input is supported.
- Read the parts of a small lambda expression.
- Use find and check its end result.
- Count matching values with count_if.
- Transform values into real output storage.
- Choose a safe value capture for a local rule.
References and further reading
Original examples and exercises accompany these primary references. Tool-specific diagnostics and support depend on your installed version.