Concepts / Sequences and Containers

Sequences and Containers

Calling push_back() or erase() works on the container, which is why it can change the number of elements. An algorithm such as replace() or sort() works on the sequence of positions, which is why it changes values but leaves the count alone.

  • Programming

A Task That Seems to Need a Bigger Container

Suppose you have a container full of values and a task to perform on them. Sometimes the task looks as if it should change how many values the container holds. You might want to add a new value at the end, or drop a value you no longer need. It is natural to wonder whether the algorithm doing the work can simply grow or shrink the container as part of the job. This article explains why that is not automatic, and how the two kinds of work differ.

The source for this topic makes one central point: changing what is stored and changing how many elements are stored are different jobs. Algorithms such as replace() and sort() can change element values without changing the number of elements. Keep that idea in mind as you read, because the rest of the article follows from it.

What an Algorithm Actually Sees

An algorithm works on a sequence of elements. The sequence is the run of positions it reads and, when the operation requires it, writes. The algorithm is handed a range of positions, usually described by a beginning and an end, and it moves through that range doing its work. This is the whole of what it knows about the data.

Here is the key consequence. A sequence does not identify the container that holds its elements. The algorithm gets a view of the positions, not a handle to the container object itself. So when an algorithm finishes, it has no built-in way to say that the container should now have more positions or fewer. Changing a value at a position is possible because the position is right there in the range. Changing how many positions exist is a different action on a different object, and the sequence alone does not provide it.

Containerholds the elements andtheir countSequence of elementspositions the algorithm canreadAlgorithm such asreplace()changes values in placeholdsreads and writes values
Why does replace() or sort() leave the container's size unchanged, even though the algorithm works on the container's elements? The algorithm reaches the elements through a sequence, but the sequence does not lead back to the container.

Read the diagram from the bottom up. The algorithm reaches the elements through the sequence. The container holds the elements, and nothing in the sequence points back to the container. Because of that missing link, the algorithm can rewrite the values it reaches, but it has no route to alter the container's count.

Changing Values Versus Changing the Element Count

Definition

Changing values means overwriting what is stored at existing positions. The number of elements stays the same. Changing the element count means adding elements to the container or removing elements from it. The number of elements goes up or down, and the container itself must be acted on.

The source gives a practical test for telling these apart. The distinction is useful whenever an operation's result seems to require a different number of elements. If the task is to change values, an algorithm such as replace() or sort() may be suitable. If the task is to add or remove elements, the operation must also have a way to act on the container itself.

QuestionChanging valuesChanging the element count
What is the goal?Make existing positions hold different valuesAdd new elements or remove existing ones
Example operations named in the sourcereplace() and sort()push_back() and erase(), or an algorithm connected to the container through back_inserter
Does the element count change?NoYes
What must the operation be able to reach?The sequence of positionsThe container itself

Two kinds of work on a container, drawn from the distinction in the source

What do you think happens?

You call replace() on a container of five values, changing every occurrence of one value to another. After the call, how many elements does the container hold?

  • Five, because replace() only changes values

  • More than five, because replacement adds new elements

  • Fewer than five, because some elements were removed

Reveal answer
Answer:

Five, because replace() changes values without changing the number of elements.

The source states that algorithms such as replace() can change element values without changing the number of elements. Replacement overwrites existing positions, so the count stays the same.

Connecting an Algorithm to a Container

Sometimes an algorithm does need to add elements, and the task is best done with an algorithm rather than a loop you write by hand. The source handles this with the back_inserter. Its role is to act as the missing connection between an algorithm and the container that should grow. Without a way to refer to the container, the sequence alone does not tell the algorithm where added elements belong.

Think of the back_inserter as an adapter placed where the algorithm writes its output. Each time the algorithm produces a value, that value is handed to the back_inserter, which adds it to the end of the container. The algorithm itself still works on a sequence, but the back_inserter gives it a way to reach the container when new elements need a home.

Source elementsvalues read one at a timestd::copycopy-style algorithmback_inserterconnection to the containerpush_back()adds one element at the endDestination containerone more element per writeeach valueeach writeeach write triggersappends
What happens step by step when std::copy writes into a back_inserter, and how does each write lead to a push_back() call that increases the container's size?

Read the flow from left to right. The copy-style algorithm takes each value from the source and writes it through the back_inserter. Each write is routed to a push_back() on the destination, which appends the value. Because every write appends one element, the destination grows as the copy proceeds. The growth comes from the connection, not from the algorithm knowing anything about containers.

Direct Container Operations: push_back and erase

When you are adding or removing elements directly, you do not need an algorithm in the middle. The source names two direct container operations: push_back(), which adds an element to the end of the container, and erase(), which removes elements. You call these on the container itself, so they can change the element count as part of their own action.

Key point

Calling push_back() or erase() works on the container, which is why it can change the number of elements. An algorithm such as replace() or sort() works on the sequence of positions, which is why it changes values but leaves the count alone.

Tracing replace() on a Small Container

The following example is an original illustration built to follow the rule from the source. It uses a container of three values and a replace() call that changes every 3 to a 9. Trace what happens to the values and to the size.

Worked example

Replacing Values Without Changing Size

A container holds the values 3, 7, and 3. A replace() call changes every 3 to 9. What does the container hold afterward, and how many elements does it have?

  1. 1
    Identify the range

    replace() receives the positions of the container. It walks through all three positions.

  2. 2
    Check position 1

    The value is 3, which matches. The algorithm overwrites that position with 9.

  3. 3
    Check position 2

    The value is 7, which does not match. The position is left as it is.

  4. 4
    Check position 3

    The value is 3, which matches. The algorithm overwrites that position with 9.

  5. 5
    Check the count

    No position was added or removed. The container still has three positions, so the size is unchanged.

Result

The container now holds 9, 7, and 9. It still has three elements.

Position 1: 3matches the targetPosition 1: 9overwrittenPosition 2: 7does not matchPosition 2: 7unchangedPosition 3: 3matches the targetPosition 3: 9overwritten
What changes in the container when replace() overwrites matching values, and what stays the same?

Compare the two states in the diagram. Positions 1 and 3 changed, and position 2 did not. The number of positions stayed at three in both states. That is the behavior the source describes: replace() changes element values without changing the number of elements.

Choosing Between an Algorithm Connection and a Direct Call

Once you know the distinction, the choice of tool follows from the task. Start by asking whether the operation must change the number of elements. If it only needs to change values, an algorithm such as replace() or sort() is a suitable choice, and it does not need a container operation at all. If the task must add or remove elements, the operation needs a way to act on the container itself.

  • Changing values only: use an algorithm such as replace() or sort(), which works on the sequence.
  • Adding elements while using an algorithm: connect the algorithm to the container with a back_inserter, so each output is added to the end.
  • Adding or removing elements directly: call push_back() to add at the end, or erase() to remove elements, on the container itself.

Mistakes Beginners Make With Sequences

  • Common mistake

    Expecting an algorithm to grow or shrink the container just because the task seems to need a different count

    What it looks like

    Assuming that replace() will add a new element when a replacement seems to call for more values

    Why it fails

    The source states that changing what is stored and changing how many elements are stored are different jobs. An algorithm working on a sequence does not have a route to the container's size.

    Do this instead

    Decide first whether the task changes values or changes the element count, then choose the tool that matches.

  • Common mistake

    Using replace() or sort() when the task is to add or remove elements

    What it looks like

    Trying to make a container longer by calling sort() on it

    Why it fails

    sort() changes the order of values in the positions it reads. It does not add or remove elements, so the count stays the same.

    Do this instead

    Use push_back() to add or erase() to remove when the element count itself must change.

  • Common mistake

    Writing an algorithm's output to a container without a connection to it

    Why it fails

    The sequence alone does not tell the algorithm where added elements belong. Without a way to refer to the container, there is no defined place for the new elements.

    Do this instead

    Connect the algorithm to the container with a back_inserter when the algorithm must add elements.

Applying the Rule to New Tasks

EASY

For each task, decide whether it changes values only, or changes the number of elements. Then name the tool you would reach for: an algorithm such as replace() or sort(), a back_inserter connection, or a direct push_back() or erase() call. Task A: change every 0 in a container to 1. Task B: add a new reading to the end of a container. Task C: arrange the values in order. Task D: remove the last element from a container.

Hints
  • Ask first whether the element count must change. Tasks A and C only change values or order.
  • Task B adds an element. Consider whether an algorithm writing its output needs a connection, or whether a direct call is simpler.
  • Task D removes an element from the container itself, which points to a direct container operation.

Key Takeaways

  • An algorithm working on a sequence can change element values, as replace() and sort() do, but it cannot by itself change the size of the container, because a sequence does not identify the container that holds its elements.
  • Changing values and changing the number of elements are different jobs. Decide which one a task requires before choosing a tool.
  • A back_inserter connects an algorithm to a container when the algorithm must add elements, so each output is added to the end of the container.
  • When adding or removing elements directly, use the container operations push_back() or erase(), which act on the container itself.

Related concepts

More concepts starting with S