HOWTO · C++

How to Copy a Vector Container Object in C++

This article demonstrates how to copy a vector container object in C++.

On this page

To copy a C++ std::vector, use its copy constructor when creating a new vector and copy assignment when replacing the contents of an existing one. For a selected range, use the range constructor. std::copy works when the destination range already has room, while std::back_inserter appends to a destination. These operations copy elements according to their types; they do not recursively copy objects reached through pointers.

Copy a vector with its copy constructor or assignment operator

Copy initialization constructs a new vector from an existing one: std::vector<int> copy = source;. Direct initialization does the same with parentheses: std::vector<int> copy(source);. If the destination already exists, use assignment: destination = source;. Assignment replaces the destination’s elements. Include <vector> for these forms.

Run this example:

#include <cstddef>
#include <iostream>
#include <vector>

int main() {
    const std::vector<int> source{2, 4, 6};
    std::vector<int> copy = source;
    std::vector<int> destination{9};
    destination = source;

    for (std::size_t i = 0; i < copy.size(); ++i) {
        if (i != 0) {
            std::cout << ' ';
        }
        std::cout << copy[i];
    }
    std::cout << '\n';
    for (std::size_t i = 0; i < destination.size(); ++i) {
        if (i != 0) {
            std::cout << ' ';
        }
        std::cout << destination[i];
    }
    std::cout << '\n';
}
2 4 6
2 4 6

This program prints each copied vector on its own line. Its std::vector<int> elements are values, so changing an integer in one vector does not change the corresponding integer in another.

Copy a range with the vector range constructor

The range constructor takes a half-open iterator range: the first iterator is included and the second is excluded. Use parentheses to distinguish this constructor from initializer-list syntax.

std::vector<int> copy(source.begin(), source.end()); creates a full range copy. For a subrange, use std::vector<int> middle(source.begin() + 1, source.end() - 1); when those iterators describe the desired elements.

The first declaration copies all elements; the second copies the interior range in this example. Both iterators must refer to a valid range in the same source vector. This is a convenient choice for a complete vector or a subrange when a new destination is needed.

Copy a range with std::copy

std::copy writes into an existing destination range. Include <algorithm>, and make sure the destination has at least as many elements as the source range before copying. The algorithm does not grow a vector by itself.

std::vector<int> destination(source.size()); followed by std::copy(source.begin(), source.end(), destination.begin()); provides a destination range large enough for the source.

For a subrange, pass its beginning and ending iterators and provide enough destination elements for that range. The source and destination ranges must not overlap in a way that violates the algorithm’s requirements.

Append copied elements with std::back_inserter

To append elements and let the vector grow as needed, include <algorithm> and <iterator> and use std::back_inserter:

For example, std::vector<int> destination{10}; followed by std::copy(source.begin(), source.end(), std::back_inserter(destination)); appends the source elements.

The original 10 remains at the front, followed by the source values. This form is useful when the destination already contains elements or when its final size is not being set in advance.

Copy elements with a loop and push_back

A loop makes the per-element operation explicit. push_back adds each copied value at the end, so an existing destination is extended.

A direct loop is for (const int& value : source) { destination.push_back(value); } after declaring std::vector<int> destination;.

For ordinary copying, the vector copy constructor or range constructor is usually clearer. A loop is appropriate when each element must be transformed or filtered as it is added. The loop copies each element according to its type, just like the standard vector operations.

Replace or insert destination elements with assign and insert

Use assign(first, last) when the destination should be replaced by a range. Use insert(position, first, last) when the source range should be placed at a position while preserving the destination’s other elements.

Use destination.assign(source.begin(), source.end()); to replace its contents. Use destination.insert(destination.begin(), source.begin(), source.end()); to insert the source range at the beginning.

The insertion position must be a valid iterator into the destination. If insertion reallocates the vector’s storage, all iterators, pointers, and references to its elements are invalidated. If no reallocation occurs, iterators and references at or after the insertion point are still invalidated; those before it remain valid. Reacquire affected iterators and references after insertion.

Understand what a vector copy duplicates

A std::vector stores its elements contiguously and owns that element storage. Copying a vector creates a separate vector containing copies of its elements. For std::vector<int>, the integer values are copied, so later assignment to one vector’s element does not alter the other’s value.

The behavior for other element types follows that type’s copy operation. For example, copying a vector of raw pointers copies the pointer values; it does not create new pointee objects. If elements are smart pointers, copying follows their own semantics, such as shared ownership for std::shared_ptr. A separate vector therefore does not always imply independent objects behind its elements.

Choose a vector-copying method

Choose copy construction or the range constructor to create a new vector. Choose copy assignment or assign to replace an existing destination. Choose insert to add a range at a position, and std::copy with std::back_inserter to append while growing the destination. Use std::copy with a sized destination when you want to write into an already allocated element range. A loop with push_back is useful when copying also involves custom per-element work.

For a new full copy, prefer the copy constructor; use a range constructor for selected elements. For an existing vector, choose assignment or assign to replace its contents, insert to place elements at a position, or std::back_inserter to append them.