Algorithms in the C++ Standard Library
The <numeric> library in C++ provides a small set of generalized numerical algorithms.
Why Programs Need Ready-Made Arithmetic Routines
Many programs need to do arithmetic over collections of values. They may need to add up a list of numbers, combine results step by step, or process a sequence of data. You could write a loop for each of these jobs every time, but C++ does not require you to write every such routine from scratch. The standard library collects a set of ready-made routines for these jobs, and the header named <numeric> is where a group of them lives.
This article follows one idea through the whole discussion: a numerical algorithm is a reusable routine, and you can find it by asking which library it belongs to and what job it does. We will use accumulate() as the running example, because the source names it as the representative member of this group.
What the <numeric> Library Contains
The <numeric> library in C++ provides a small set of generalized numerical algorithms.
The section that introduces this topic makes two claims you should hold onto. First, the <numeric> library contains numerical algorithms. Second, the set it offers is small, and accumulate() is named as one member of it. Together these claims tell you how to think about the library: it is a focused toolkit, not an exhaustive catalogue of every mathematical operation. If you need a numerical routine, checking <numeric> is a sensible first step, but you should not expect it to contain everything.
Reading the Library, Header, and Algorithm Relationship
It helps to see how the pieces relate. The <numeric> header is the container. Inside it sits the group of numerical algorithms. accumulate() is one specific member of that group. Reading this relationship from the top down makes it easy to answer questions such as where a numerical routine comes from, or what a named routine belongs to.
Read the diagram from the top down. If someone asks where accumulate() belongs, the answer comes from its role, which is summing or combining numbers, and from its library, which is the <numeric> header. You do not need to have memorized the name in isolation.
Generalized Numerical Algorithms
Generalized numerical algorithms are reusable, general-purpose routines for numerical work rather than one-off code. The word generalized signals that the routine is not tied to a single task. The same routine can serve many numerical jobs, and the parts that change from job to job can be supplied by the caller.
Tracing How accumulate() Combines Values
accumulate() takes a range of values and combines them into a single result. It begins with a starting value, called the initial value, and then folds in each element one at a time. Each step takes the running result so far and combines it with the next element. When the range is exhausted, the running result is returned. The best way to understand this is to watch the running value change.
Tracing accumulate() over three values
Combine the values 3, 1, and 4 with accumulate(), starting from the initial value 0, using ordinary addition.
- 1Start
The running result begins at the initial value 0.
- 2Fold in 3
0 plus 3 gives a running result of 3.
- 3Fold in 1
3 plus 1 gives a running result of 4.
- 4Fold in 4
4 plus 4 gives a running result of 8. No elements remain, so the loop stops.
accumulate() returns 8.
Notice that the running result carries forward from one step to the next. Each step does not start over; it builds on what the previous step produced. This is the reason a single call can turn a whole range of values into one answer.
Swapping the Combining Operation
The word generalized matters here. The routine is not fixed to addition. The rule used to combine the running result with each element is a replaceable part. With ordinary addition, the routine sums values. With a different combining rule, such as multiplication, the same routine multiplies values instead. The traversal and the step-by-step carrying of the running result stay the same; only the combining rule changes.
What do you think happens?
If the initial value is 1 and the combining rule is multiplication, what does accumulate() return for the values 3, 1, and 4?
Reveal answer
12
Start at 1. Multiply by 3 to get 3, multiply by 1 to get 3, then multiply by 4 to get 12. The traversal is identical to the addition case; only the combining rule differs.
Mistakes Beginners Make with Numerical Routines
Common mistake Assuming <numeric> contains every mathematical operation
Why it failsThe source describes the set in <numeric> as small, and it is a focused toolkit rather than an exhaustive catalogue.
Do this insteadCheck <numeric> first for numerical routines, but expect that some tasks will need code you write yourself or routines from elsewhere.
Common mistake Memorizing accumulate() as an isolated name
Why it failsA name learned without its library and role is hard to recall or to find when you need a similar routine.
Do this insteadLocate it by reasoning: it is a numerical algorithm, so it belongs to <numeric>, and its role is combining a range of values into one result.
Common mistake Thinking the starting value does not matter
What it looks likeAccumulating 3, 1, and 4 from 0 with addition gives 8, but the same values from 10 give 18.
Why it failsThe initial value is the first running result, so every later step builds on it.
Do this insteadAlways decide the initial value deliberately, because it sets the starting point of the fold.
Common mistake Treating the combining rule as fixed to addition
Why it failsGeneralized numerical algorithms let the combining rule be replaced, so the routine is not tied to summing.
Do this insteadRecognize that the same routine can be reused with a different combining rule, such as multiplication.
Practice Locating a Numerical Routine
A colleague asks where to look for a routine that combines a list of numbers into one total. Using only the reasoning from this article, explain which library you would check first, what role the routine plays, and what starting value you would choose if you wanted the total to begin at 10.
Hints
- Ask which library the source places numerical algorithms in.
- Think about what the routine does to a range of values: it combines them into one result.
- The starting value is the initial value of the running result.
Trace accumulate() over the values 2, 5, and 2 with an initial value of 1 and multiplication as the combining rule. Write down the running result after each element and state the final returned value.
Hints
- Start with the running result equal to 1.
- After each element, replace the running result with the running result multiplied by that element.
Checking Your Understanding
Key Takeaways
- The <numeric> library in C++ provides a small set of generalized numerical algorithms, and it is a focused toolkit rather than an exhaustive one.
- Generalized numerical algorithms are reusable routines whose combining rule can be replaced, so the same routine serves many numerical jobs.
accumulate()is a numerical algorithm in <numeric> that folds a range of values into one result, starting from an initial value.- To locate a numerical routine, reason from its library and its role: the header is the container, the algorithms sit inside it, and
accumulate()is one member.