Question

How to Append One std::vector to Another in C++

cppstlstdvector

Question

I have two standard C++ vectors:

std::vector<int> a;
std::vector<int> b;

Assume both vectors contain around 30 elements.

How can I append all elements of b to the end of a?

One possible approach is to loop through b and call push_back() for each element, but I would prefer a cleaner standard-library solution.

Short Answer

By the end of this page, you will understand how to append one std::vector to another in C++, why insert() is the usual solution, how it works internally, when push_back() loops are still acceptable, and what mistakes to avoid when combining vectors.

Concept

In C++, a std::vector stores elements in a contiguous dynamic array. When you want to append one vector to another, you usually want to copy a whole range of elements from the second vector into the first.

The standard way to do this is with vector::insert().

a.insert(a.end(), b.begin(), b.end());

This means:

  • insert into a
  • at position a.end() (the end of a)
  • all elements from the range [b.begin(), b.end())

This is important because:

  • it is concise
  • it uses the standard library idiomatically
  • it expresses your intent clearly: append a range
  • it can be more efficient and readable than manually looping

When appending vectors, C++ may need to grow the destination vector's storage. If a does not have enough capacity, it allocates more memory and copies or moves elements into the new storage.

For beginner-friendly code, insert() is the most common and direct solution for concatenating vectors.

Mental Model

Think of a std::vector as a row of boxes on a shelf.

  • a is one row of boxes already holding values.
  • b is another row of boxes.
  • Appending b to a means taking all boxes from b and placing copies of them at the end of a's row.

insert() is like saying:

Starting at the end of shelf a, place every item from shelf b in order.

You do not need to move one item at a time manually in your own loop unless you want special behavior.

Take Quiz

Syntax and Examples

The usual syntax is:

a.insert(a.end(), b.begin(), b.end());

Example 1: Append one vector to another

#include <iostream>
#include <vector>

int main() {
    std::vector<int> a{1, 2, 3};
    std::vector<int> b{4, 5, 6};

    a.insert(a.end(), b.begin(), b.end());

    for (int value : a) {
        std::cout << value << ' ';
    }
}

Output:

1 2 3 4 5 6

Explanation

  • a.end() says to insert at the end of a
  • b.begin() and b.end() define the range of elements from b
  • all elements of b are copied into a

Example 2: Reserving space first

If you know you will append many elements, you can reserve capacity first:

#include <vector>

int main() {
    std::vector<int> a{1, 2, 3};
    std::vector<int> b{4, 5, 6};

    a.reserve(a.size() + b.size());
    a.insert(a.end(), b.begin(), b.end());
}

This can reduce reallocations.

Example 3: Manual loop with push_back()

This is valid, just less concise:

for (int value : b) {
    a.push_back(value);
}

This is not wrong. It is simply more verbose when your goal is to append a whole range unchanged.

Step by Step Execution

Consider this example:

std::vector<int> a{10, 20};
std::vector<int> b{30, 40, 50};

a.insert(a.end(), b.begin(), b.end());

Step by step:

  1. a starts as:
[10, 20]
  1. b starts as:
[30, 40, 50]
  1. a.end() points just past the last element of a

  2. b.begin() points to 30

  3. b.end() points just past 50

  4. insert() copies the range from b into a at the end position

  5. After insertion, a becomes:

[10, 20, 30, 40, 50]
  1. b stays unchanged:
[30, 40, 50]

If a lacks enough capacity, it may allocate a larger block of memory before copying the old and new elements into the new storage.

Real World Use Cases

Appending vectors appears often in real programs.

1. Merging batches of data

A program may read records from multiple files and store them in one vector:

allRecords.insert(allRecords.end(), batch.begin(), batch.end());

2. Combining API or database results

If data is loaded page by page, each new page can be appended to the existing result set.

3. Building token lists or parsed output

A parser may collect tokens from multiple stages and append them into one final sequence.

4. Game development

A game might combine lists of visible objects, events, or commands into one processing queue.

5. Logging and telemetry

Applications sometimes collect event chunks in separate vectors and then merge them for processing or writing to disk.

Take Quiz

Real Codebase Usage

In real codebases, developers often combine insert() with a few common patterns.

Reserve before append

When size is predictable, this is a common optimization:

items.reserve(items.size() + newItems.size());
items.insert(items.end(), newItems.begin(), newItems.end());

Guard clause for empty input

if (b.empty()) {
    return;
}

a.insert(a.end(), b.begin(), b.end());

This can make intent clearer, especially in functions.

Appending results from helper functions

std::vector<int> loadPart1();
std::vector<int> loadPart2();

std::vector<int> result = loadPart1();
std::vector<int> extra = loadPart2();
result.insert(result.end(), extra.begin(), extra.end());

Validation before merging

Sometimes data must be checked before appending:

for (int value : b) {
    if (value >= 0) {
        a.push_back(value);
    }
}

If you need filtering or transformation, a loop is often better than insert().

Move instead of copy

In some codebases, elements are moved when the source is no longer needed:

#include <iterator>

a.insert(a.end(), std::make_move_iterator(b.begin()), std::make_move_iterator(b.end()));

This is more advanced and mainly useful for expensive-to-copy types.

Common Mistakes

1. Using push_back() with the whole vector

This does not work because push_back() adds one element, not a whole range.

Broken code:

std::vector<int> a{1, 2};
std::vector<int> b{3, 4};

a.push_back(b); // error

Why it fails:

  • a stores int
  • b is a std::vector<int>
  • an int vector cannot push a whole vector as one int

2. Forgetting the insert position

Broken code:

a.insert(b.begin(), b.end());

Why it fails:

  • insert() needs a position in a first
  • then the range to insert

Correct version:

a.insert(a.end(), b.begin(), b.end());

3. Confusing append with replacement

insert() adds elements; it does not remove existing ones.

std::vector<int> a{1, 2};
std::vector<int> b{3, 4};

a.insert(a.end(), b.begin(), b.end());
// a is now {1, 2, 3, 4}

If you wanted a to become exactly b, use assignment:

a = b;

4. Ignoring reallocation cost

If many appends happen repeatedly, not reserving capacity can cause extra reallocations.

Better:

a.reserve(a.size() + b.size());
a.insert(a.end(), b.begin(), b.end());

5. Modifying a vector while using invalidated iterators

If insertion causes reallocation, iterators into a may become invalid.

Be careful when storing iterators or references into a vector before appending to it.

Comparisons

ApproachBest forProsCons
a.insert(a.end(), b.begin(), b.end())Appending all elements from another vectorClear, standard, conciseCopies elements unless move iterators are used
Loop with push_back()Custom logic while appendingFlexible, easy to filter/transformMore verbose
Assignment a = bReplacing contents of aSimpleDoes not append
std::copy with std::back_inserter(a)Generic algorithms styleWorks well with algorithm pipelinesSlightly less direct for beginners

insert() vs std::copy

These are similar for appending:

a.insert(a.end(), b.begin(), b.end());
std::copy(b.begin(), b.end(), std::back_inserter(a));

For beginners, insert() is usually simpler when copying one vector to the end of another.

insert() vs manual loop

Use insert() when:

  • you want to append the whole range unchanged
  • readability matters
  • you want standard vector range insertion

Use a loop when:

  • you need to skip some elements
  • you need to transform values
  • you need custom validation or logging
Take Quiz

Cheat Sheet

// Append vector b to vector a
std::vector<int> a;
std::vector<int> b;
a.insert(a.end(), b.begin(), b.end());

Quick rules

  • insert(pos, first, last) inserts a range at position pos
  • to append, use a.end() as the position
  • source vector b is unchanged when using normal iterators
  • reserve capacity first if performance matters

Useful pattern

a.reserve(a.size() + b.size());
a.insert(a.end(), b.begin(), b.end());

Alternative

for (int x : b) {
    a.push_back(x);
}

If you need transformation or filtering

Use a loop instead of insert().

Common error

a.push_back(b); // wrong: b is a vector, not an int

Another valid approach

#include <algorithm>
#include <iterator>

std::copy(b.begin(), b.end(), std::back_inserter(a));

FAQ

How do I append one std::vector to another in C++?

Use:

a.insert(a.end(), b.begin(), b.end());

Does insert() modify the second vector?

No. In the normal form, it copies elements from b into a. b remains unchanged.

Is looping with push_back() wrong?

No. It is completely valid. insert() is just shorter and clearer when appending a whole range.

Should I call reserve() before appending?

If performance matters and you know the final size, yes. It can reduce reallocations.

Can I append vectors of custom objects?

Yes, as long as the element types are compatible and copyable or movable as needed.

What if I want to move elements instead of copy them?

You can use move iterators:

a.insert(a.end(), std::make_move_iterator(b.begin()), std::make_move_iterator(b.end()));

Can I use std::copy instead of insert()?

Yes:

std::copy(b.begin(), b.end(), std::back_inserter(a));

Both are valid, but insert() is often more direct for vectors.

Take Quiz

Mini Project

Description

Build a small C++ program that combines multiple groups of numbers into a single list. This demonstrates how appending vectors works in a realistic situation, such as merging batches of data loaded from different sources.

Goal

Create a program that appends one vector to another and prints the combined result.

Requirements

  1. Create two std::vector<int> variables with sample values.
  2. Append the second vector to the first using a standard-library approach.
  3. Print the final combined vector.
  4. Reserve capacity before appending.
  5. Keep the second vector unchanged.
Take Quiz

Keep learning

Related questions

View more