Concepts / Algorithms in the C++ Standard Library

Algorithms in the C++ Standard Library

The <numeric> library in C++ provides a small set of generalized numerical algorithms.

  • Programming

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

Definition

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.

std namespacestandard library<numeric> headernumerical algorithmsaccumulate()numerical algorithmprovidescontains
How the std namespace, the <numeric> header, and the numerical algorithms inside it relate, so accumulate() can be found by reasoning from its library.

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.

Worked example

Tracing accumulate() over three values

Combine the values 3, 1, and 4 with accumulate(), starting from the initial value 0, using ordinary addition.

  1. 1
    Start

    The running result begins at the initial value 0.

  2. 2
    Fold in 3

    0 plus 3 gives a running result of 3.

  3. 3
    Fold in 1

    3 plus 1 gives a running result of 4.

  4. 4
    Fold in 4

    4 plus 4 gives a running result of 8. No elements remain, so the loop stops.

Result

accumulate() returns 8.

start: 0initial valueafter 3: 3running resultafter 1: 4running resultafter 4: 8running resultresult: 8returned valueadd 3add 1add 4range ends
How accumulate() combines the elements one at a time, starting from the initial value, to arrive at a single result.

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.

start 0initial valuestart 1initial valueadd 3, 1, 4combining rule: plusmultiply 3, 1, 4combining rule: timesresult 8sumresult 12productfold indonefold indone
What changes when accumulate() uses default addition versus multiplication, and why the same algorithm is reusable for both.

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?

  • 6

  • 8

  • 12

  • 24

Reveal answer
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 fails

    The source describes the set in <numeric> as small, and it is a focused toolkit rather than an exhaustive catalogue.

    Do this instead

    Check <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 fails

    A name learned without its library and role is hard to recall or to find when you need a similar routine.

    Do this instead

    Locate 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 like

    Accumulating 3, 1, and 4 from 0 with addition gives 8, but the same values from 10 give 18.

    Why it fails

    The initial value is the first running result, so every later step builds on it.

    Do this instead

    Always 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 fails

    Generalized numerical algorithms let the combining rule be replaced, so the routine is not tied to summing.

    Do this instead

    Recognize that the same routine can be reused with a different combining rule, such as multiplication.

Practice Locating a Numerical Routine

EASY

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.
MEDIUM

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.

Related concepts

More concepts starting with A