Copying Algorithms

An introduction to the 7 copying algorithms in the C++ standard library: copy(), copy_n(), copy_if(), copy_backward(), reverse_copy(), rotate_copy(), and unique_copy().
This lesson is part of theÂ course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, Unlimited Access
Ryan McCombe
Updated

In this lesson, we cover the most essential copying algorithms. We will cover the seven main algorithms for copying objects from one container to another: copy(), copy_backward(), rotate_copy(), reverse_copy(), copy_if(), copy_n() and unique_copy().

All the algorithms in this section are available within the <algorithm>Â header:

#include <algorithm>

What it means for an object to be copied is defined by the copy semantics of its type. We cover copy semantics in more detail in a separateÂ lesson:

std::ranges::copy()

The standard copy() algorithm will copy every element from a source range to a new destination. The destination where elements will be copied to is defined by passing an iterator as the secondÂ argument.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::copy(Source, Destination.begin());

for (auto i : Destination) {
std::cout << i << ", ";
}
}
1, 2, 3, 0, 0, 0,

We do not need to copy to the beginning of the destination container. We can provide an iterator that pointsÂ anywhere:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::copy(Source,
Destination.begin() + 2);

for (auto i : Destination) {
std::cout << i << ", ";
}
}
0, 0, 1, 2, 3, 0,

We are responsible for ensuring that the location the destination iterator points to has enough space to receive ourÂ copies.

Return Type

The type returned from std::ranges::copy() is a std::ranges::in_out_result which is commonly aliased to types like std::ranges::copy_result. This type has twoÂ fields:

• in: An iterator for our input range, pointing at the location where the sentinel was encountered. In the previous example, this is equivalent to Source.end()
• out: An iterator for our destination, pointing beyond the last element that was copied
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::copy_result Result{
std::ranges::copy(Source,
Destination.begin())};

int64_t InputSize{
std::distance(Source.begin(), Result.in)};

std::cout << "The input size was " << InputSize;

int64_t OutputPosition{std::distance(
Destination.begin(), Result.out - 1)};

std::cout << "\nThe last element copied is at "
"position "
<< OutputPosition
<< "\nin the destination";

std::cout << "\nIts value is "
<< Destination[OutputPosition];
}
The input size was 3
The last element copied is at position 2
in the destination
Its value is 3

The std::ranges::in_out_result type supports structured binding for easierÂ use:

auto [in, out]{std::ranges::copy(
Source, Destination.begin())};

std::ranges::copy_backward()

The copy_backward() algorithm accepts a source input range, and an iterator pointing at where we want the copies toÂ end.

Elements from the source are copied in reverse order, with the destination iterator also moving in reverse order. The effect of this is that the relative order of the source elements is maintained within theÂ destination:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::copy_backward(Source,
Destination.end());

for (auto i : Destination) {
std::cout << i << ", ";
}
}
0, 0, 0, 1, 2, 3,

Return Type

Similar to copy(), the copy_backward() algorithm returns a std::ranges::in_out_result, with the sameÂ properties:

• in - An iterator for the input range, pointing at where the sentinel was triggered. In the previous example, this is equivalent to Source.end()
• out - An iterator for the destination range, pointing to the last element moved.

Since elements are copied from right to left, the out iterator will point to the leftmost element that was copied within theÂ destination:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3};
std::vector Destination{0, 0, 0, 0, 0};

auto [in, out]{std::ranges::copy_backward(
Source, Destination.end())};

std::cout << "Values in Destination: ";
for (auto& Num : Destination) {
std::cout << Num << ", ";
}

std::cout << "\nThe input had "
<< std::distance(Source.begin(), in)
<< " objects\n";

std::cout << "The output iterator is at "
"position "
<< std::distance(
Destination.begin(), out);

std::cout << "\nThe last element copied was "
<< *out;
}
Values in Destination: 0, 0, 1, 2, 3,
The output iterator is at position 2
The last element copied was 1

Given copy_backward() traverses our containers in reverse order, it relies on our input range and output iterator supporting bidirectional iteration. For example, we would not be able to use copy_backward() with a std::forward_list, as this container only supports forwardÂ iteration.

Why do we need copy_backward()?

It may seem weird that we have both a copy() and copy_backward() algorithm. The reason we have both is to deal with situations where our input and output ranges are overlapping. The most common reason for this is when weâ€™re trying to copy objects to a different location within the sameÂ container.

For example, letâ€™s imagine we have the collection {1, 2, 3, 0, 0} and we want to copy the 1, 2 and 3 to the location two positions to the right, giving us {1, 2, 1, 2, 3}.

If we try to do this with copy(), we may not get what weÂ want:

#include <algorithm>
#include <iostream>
#include <vector>

struct T {/*...*/};

int main() {
std::vector<T> Values{
T{1}, T{2}, T{3}, T{0}, T{0}};

std::ranges::copy(
Values.begin(),
Values.begin() + 3,
// Undefined behaviour - this
// destination is within the input range
Values.begin() + 2);

for (T& Object : Values) {
std::cout << Object.Value << ", ";
}
}
1, 2, 1, 2, 1,

This is because the algorithmâ€™s first copy action causes the 1 to overwrite the 3. We hadnâ€™t copied the 3 to its new position yet, and now weâ€™ve lost it. If we use copy_backward() instead, we get the desiredÂ result:

#include <algorithm>
#include <iostream>
#include <vector>

struct T {/*...*/};

int main() {
std::vector<T> Values{
T{1}, T{2}, T{3}, T{0}, T{0}};

std::ranges::copy_backward(
Values.begin(),
Values.begin() + 3,
// This is now valid - the destination is
// no longer within the source range
Values.end());

for (T& Object : Values) {
std::cout << Object.Value << ", ";
}
}
1, 2, 1, 2, 3,

In general, when using the copy() or copy_backward() algorithm, if the destination iterator is within the source range, the behaviour is undefined. When copying elements to a different location within the same container, we can deal with this by following a simpleÂ rule:

• When copying objects to a position to the right of where they currently are, as was the case in the previous example, use copy_backward()
• If copying objects to a position to the left of where they currently are, use copy()

std::ranges::reverse_copy()

The reverse_copy algorithm accepts an input range and a destination iterator. The input range is copied from right to left, whilst the destination iterator moves forward. The effect of this is that the source elements are copied into the destination in reverseÂ order:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::reverse_copy(
Source, Destination.begin());

for (auto i : Destination) {
std::cout << i << ", ";
}
}
3, 2, 1, 0, 0, 0,

Return Type

The reverse_copy() algorithm returns a struct with the type std::ranges::in_out_result. This type is aliased to std::ranges::reverse_copy_result. The output has twoÂ properties:

• in - A past-the-end iterator for the input range
• out - A past-the-end iterator for the copied input range, within the destination range
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3};
std::vector Destination{0, 0, 0, 0, 0, 0};

auto [in, out] = std::ranges::reverse_copy(
Source, Destination.begin());

for (auto i : Destination) {
std::cout << i << ", ";
}

std::cout << "\nThe input had "
<< std::distance(Source.begin(), in)
<< " objects\n";

std::cout << "The output iterator is at "
"position "
<< std::distance(
Destination.begin(), out);

std::cout << "\nThe last element copied was "
<< *(out - 1);
}
3, 2, 1, 0, 0, 0,
The output iterator is at position 3
The last element copied was 1

std::ranges::rotate_copy()

We can think of rotation as shifting everything left or right within a container. Objects that fall off the edge are rotated around to the opposite edge. For example, imagine we had thisÂ container:

{1, 2, 3, 4, 5, 6}

Rotating the container by 1 step to the right would result inÂ this:

{6, 1, 2, 3, 4, 5}

Everything moved one step to the right. The 6 had no room to move right, so it rotated around to theÂ start.

The rotate_copy() algorithm combines a rotation and a copy. Elements from a source container are copied to a destination container, in a rotated order. The algorithm has threeÂ arguments:

• The source range where the objects are to be copied from
• An iterator pointing at the first object we want to copy - ie, this argument controls the amount of rotation
• An iterator pointing at where we should start copying objects to

Below, we tell rotate_copy() that we want the first object copied to be Source.end() - 1, which is the 6. Therefore, relative to the Source, the Destination receives the copies rotated by one position to theÂ right:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::rotate_copy(Source,
Source.end() - 1,
Destination.begin());

std::cout << "-----Source: ";
for (auto i : Source) {
std::cout << i << ", ";
}

std::cout << "\nDestination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}
}
-----Source: 1, 2, 3, 4, 5, 6,
Destination: 6, 1, 2, 3, 4, 5,

Return Type

The rotate_copy() algorithm returns a struct with the type std::ranges::in_out_result. This type is aliased to std::ranges::rotate_copy_result. The output has twoÂ properties:

• in - An iterator for the input range, pointing at where the sentinel was encountered. In the previous example, itâ€™s equivalent to Source.end()
• out - An iterator for the output location, pointing beyond the last element that was copied
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector Destination{0, 0, 0, 0,
0, 0, 0, 0};

auto [in, out]{std::ranges::rotate_copy(
Source, Source.end() - 1,
Destination.begin())};

for (auto i : Destination) {
std::cout << i << ", ";
}

std::cout << "\nThe input had "
<< std::distance(Source.begin(), in)
<< " objects\n";

std::cout << "The output iterator is at "
"position "
<< std::distance(
Destination.begin(), out);

std::cout << "\nThe last element copied was "
<< *(out - 1);
}
6, 1, 2, 3, 4, 5, 0, 0,
The output iterator is at position 6
The last element copied was 5

std::ranges::copy_n()

The std::ranges::copy_n() algorithm copies a limited number of objects from a source range to a destination range. The function has 3Â parameters:

• An iterator pointing to the beginning of the source range
• An integer representing how many objects to copy
• An iterator pointing to the start of the destination range, where objects are to be copied

The "n" in the name of this function relates to the convention of using a variable called "n" to represent a quantity of objects. In this case, the n is the value we pass as the secondÂ argument.

We should ensure that the location starting at our source iterator has at least n elements, and that the location starting at our destination iterator has enough space to storeÂ them.

Below, we copy 4 elements from our Source to our Destination:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::copy_n(Source.begin(), 4,
Destination.begin());

for (auto i : Destination) {
std::cout << i << ", ";
}
}
1, 2, 3, 4, 0, 0,

Return Type

The std::ranges::copy_n() algorithm returns a std::ranges::copy_n_result, which is an alias for std::ranges::in_out_result. This is a struct with twoÂ properties:

• in - an iterator for the input range, pointing beyond the last element copied. In the previous example, this is equivalent to Source.begin() + 4
• out - an iterator for the output range, pointing beyond the last element copied. In the previous example, this is equivalent to Destination.begin() + 4
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector Destination{0, 0, 0, 0, 0, 0};

auto [in, out]{std::ranges::copy_n(
Source.begin(), 4, Destination.begin())};

std::cout << "Values in Destination: ";
for (auto& Num : Destination) {
std::cout << Num << ", ";
}

std::cout
<< "\nThe input iterator is at position "
<< std::distance(Source.begin(), in);

std::cout << "\nThe output iterator is at "
"position "
<< std::distance(
Destination.begin(), out);

std::cout << "\nThe last element copied was "
<< *(out - 1);
}
Values in Destination: 1, 2, 3, 4, 0, 0,
The input iterator is at position 4
The output iterator is at position 4
The last element copied was 4

std::ranges::copy_if()

The std::ranges::copy_if() algorithm works similarly to std::ranges::copy(), but it accepts a predicate function as the third argument. Each object in the source range will be passed to the predicate, and it will be copied only if that predicate call returns true.

Below, we use std::ranges::copy_if() to copy only the even numbers from the sourceÂ range:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector<int> Destination;
Destination.resize(Source.size());

auto isEven{
[](const int& x) { return x % 2 == 0; }};

std::ranges::copy_if(
Source, Destination.begin(), isEven);

std::cout << "-----Source: ";
for (auto i : Source) {
std::cout << i << ", ";
}

std::cout << "\nDestination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}
}
-----Source: 1, 2, 3, 4, 5, 6,
Destination: 2, 4, 6, 0, 0, 0,

Predicates

A function that returns a boolean is sometimes called a predicate. Therefore, isEven() in our previous program is an example of aÂ predicate.

Return Type

The type returned from std::ranges::copy_if() is a std::ranges::in_out_result which is aliased as std::ranges::copy_if_result. This type has twoÂ fields:

• in: An iterator for the input range, pointing to where the sentinel was encountered. In the previous example, it is equivalent to Source.end()
• out: An iterator within the destination location, pointing beyond the last element copied
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector<int> Destination;
Destination.resize(Source.size());

auto isEven{
[](const int& x) { return x % 2 == 0; }};

auto [in, out]{std::ranges::copy_if(
Source, Destination.begin(), isEven)};

std::cout << "-----Source: ";
for (auto i : Source) {
std::cout << i << ", ";
}

std::cout << "\nDestination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}

std::cout << "\nThe input had "
<< std::distance(Source.begin(), in)
<< " objects\n";

std::cout << "The output iterator is at "
"position "
<< std::distance(
Destination.begin(), out);

std::cout << "\nThe last element copied was "
<< *(out - 1);
}
-----Source: 1, 2, 3, 4, 5, 6,
Destination: 2, 4, 6, 0, 0, 0,
The output iterator is at position 3
The last element copied was 6

Projection Function

The std::ranges::copy_if() algorithm additionally accepts an optional 4th argument, for a projection function. We cover projection in more detail in a dedicatedÂ lesson:

Below, we project our Player objects to their level using the GetLevel() member function. This causes our predicate to receive an int, and return true if that integer is greater than 20. The combined effect of this is that our copy_if() invocation copies players if their level is above 20:

#include <algorithm>
#include <iostream>
#include <vector>

class Player {/*...*/};

int main() {
std::vector<Player> Source;
Source.emplace_back("Roderick", 10);
Source.emplace_back("Anna", 50);
Source.emplace_back("Robert", 100);

std::vector<Player> Destination;
Destination.resize(Source.size());

auto isOver20{[](int x) {
return x > 20;
}};

auto [in, out] = std::ranges::copy_if(
Source, Destination.begin(), isOver20,
&Player::GetLevel);

std::cout << "Source: ";
for (Player& P : Source) {
std::cout << P.GetName() << ", ";
}

std::cout << "\nCopied: ";
for (Player& P : std::ranges::subrange{
Destination.begin(), out}) {
std::cout << P.GetName() << ", ";
}
}
Source: Roderick, Anna, Robert,
Copied: Anna, Robert,

std::ranges::unique_copy()

The unique_copy() algorithm has a fairly niche use. It works similarly to std::ranges::copy(), but will not copy any object that passed an equality check with the previousÂ object.

For example, copying 1, 2, 2, 1 will yield 1, 2, 1. The second 2 is skipped as it was equal to the previous object in the original range. Only the first object in each group of equal objects will be copied. As such, copying 1, 2, 2, 2, 1 will also yield 1, 2, 1.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 1, 2, 1, 2, 2, 2, 2};
std::vector<int> Destination;
Destination.resize(Source.size());

std::ranges::unique_copy(Source,
Destination.begin());

std::cout << "-----Source: ";
for (auto i : Source) {
std::cout << i << ", ";
}

std::cout << "\nDestination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}
}
-----Source: 1, 1, 2, 1, 2, 2, 2, 2,
Destination: 1, 2, 1, 2, 0, 0, 0, 0,

Return Type

The unique_copy() algorithm returns a struct with the type std::ranges::in_out_result. This type is aliased to std::ranges::unique_copy_result. The output has twoÂ properties:

• in - An iterator for the input range, pointing at where the sentinel was found. In the previous example, it is equivalent to Source.end()
• out - An iterator for the output location, pointing beyond the last object that was copied
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 1, 2, 1, 2, 2, 2, 2};
std::vector<int> Destination;
Destination.resize(Source.size());

auto [in, out]{std::ranges::unique_copy(
Source, Destination.begin())};

std::cout << "-----Source: ";
for (auto i : Source) {
std::cout << i << ", ";
}

std::cout << "\nDestination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}

std::cout << "\nThe input had "
<< std::distance(Source.begin(), in)
<< " objects\n";

std::cout << "The output iterator is at "
"position "
<< std::distance(
Destination.begin(), out);

std::cout << "\nThe last element copied was "
<< *(out - 1);
}
-----Source: 1, 1, 2, 1, 2, 2, 2, 2,
Destination: 1, 2, 1, 2, 0, 0, 0, 0,
The output iterator is at position 4
The last element copied was 2

Custom Comparison Function

By default, the unique_copy() algorithm uses the equality operator == to determine if adjacent objects are equal. We can control this by passing our own comparison function as an additionalÂ argument.

This function will receive two objects from our input, and should return true if the algorithm should consider those objects equal. Below, we use this to treat two objects in our collection as being equal if their absolute value isÂ equal:

#include <algorithm>
#include <iostream>
#include <vector>

bool AbsEqual(int x, int y) {
return std::abs(x) == std::abs(y);
}

int main() {
std::vector Source{1, -1, -2, 2, 3};
std::vector<int> Destination;
Destination.resize(Source.size());

std::ranges::unique_copy(
Source, Destination.begin(), AbsEqual);

std::cout << "Source: ";
for (auto i : Source) {
std::cout << i << ", ";
}

std::cout << "\nDestination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}
}
Source: 1, -1, -2, 2, 3,
Destination: 1, -2, 3, 0, 0,

Projection Function

The unique_copy() algorithm allows us to provide a projection function. Our objects will be passed to this projection function, and what that function returns will be used to determine whether the original objects areÂ equal.

Below, we want to consider two Player objects to be equal if they have the same Name. So, we use the GetName member function to cause the comparison function to receive those names, instead of the full PlayerÂ objects.

We want to use the default comparison function - the == operator - so we pass {} as the third argument. In this case, it will specifically use the == operator on std::string, as our projection function is returning std::stringÂ objects:

#include <algorithm>
#include <iostream>
#include <vector>

class Player {/*...*/};

int main() {
std::vector<Player> Source;
Source.emplace_back("Roderick", 10);
Source.emplace_back("Anna", 50);
Source.emplace_back("Anna", 50);
Source.emplace_back("Robert", 100);
Source.emplace_back("Robert", 100);

std::vector<Player> Destination;
Destination.resize(Source.size());

auto [in, out] = std::ranges::unique_copy(
Source, Destination.begin(), {},
&Player::GetName);

std::cout << "Source: ";
for (Player& P : Source) {
std::cout << P.GetName() << ", ";
}

std::cout << "\nCopied: ";
for (Player& P : std::ranges::subrange{
Destination.begin(), out}) {
std::cout << P.GetName() << ", ";
}
}
Source: Roderick, Anna, Anna, Robert, Robert,
Copied: Roderick, Anna, Robert,

Using Iterator-Sentinel Pairs

Our previous examples tended to provide our range as a single argument but, as usual, we can instead provide it as an iterator-sentinel pair. Below, we use this technique to copy only a subset of the objects within ourÂ collection:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::ranges::copy(Source.begin() + 1,
Source.end() - 1, Destination.begin());

std::cout << "Destination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}
}
Destination: 2, 3, 4, 5, 0, 0,

Using Iterator-Based Algorithms

In this lesson, weâ€™re focusing on the versions of these algorithms that work with ranges, a C++20Â feature.

Alternative versions of these algorithms work directly with iterators. These alternative functions are also in the <algorithm> library and can be used by excluding the ranges namespace from ourÂ identifier.

Below, we rewrite the first example to use std::copy() instead of std::ranges::copy(). Instead of passing the source as a range, we pass two iterators, representing the first and last element toÂ copy:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector Source{1, 2, 3, 4, 5, 6};
std::vector Destination{0, 0, 0, 0, 0, 0};

std::copy(Source.begin() + 1,
Source.end() - 1, Destination.begin());

std::cout << "Destination: ";
for (auto i : Destination) {
std::cout << i << ", ";
}
}
Destination: 2, 3, 4, 5, 0, 0,

Compared to their more modern range-based counterparts, these variations have threeÂ disadvantages:

• We must provide our input as two arguments - we donâ€™t have the option of providing a container directly
• The end of our input be provided as an iterator, rather than the more flexible sentinel option of the range-based algorithms
• They do not support projection functions

However, they remain in common use, and are usually our best options when working on projects targeting specifications prior toÂ C++20.

Summary

In this lesson, we introduced various std::ranges algorithms for copying elements within and between containers. Here are the main points studentsÂ learned:

• The basic usage of std::ranges::copy() for copying elements from a source range to a destination.
• How to use std::ranges::copy_backward() for copying elements in reverse order, useful for handling overlapping ranges.
• Using std::ranges::reverse_copy() to invert the order of elements during the copy process.
• Using std::ranges::rotate_copy() to perform rotation operations combined with copying, to shift elements.
• The std::ranges::copy_n() algorithm for copying a specified number of elements from one range to another.
• The selective copying of elements based on a predicate using std::ranges::copy_if(), including the use of predicates and projection functions.
• Employing std::ranges::unique_copy() to copy elements while omitting consecutive duplicates, with options for custom comparison and projection functions.
• Using iterator-sentinel pairs for specifying ranges in copy operations.
• Differences between iterator-based and range-based copy algorithms, including the limitations of the older iterator-based techniques.

Next Lesson

Removal Algorithms

An overview of the key C++ standard library algorithms for removing objects from containers. We cover remove(), remove_if(), remove_copy(), and remove_copy_if().
New: AI-Powered AssistanceAI Assistance

Questions and HelpNeed Help?

Get instant help using our free AI assistant, powered by state-of-the-art language models.

Updated
Lesson Contents

Copying Algorithms

An introduction to the 7 copying algorithms in the C++ standard library: copy(), copy_n(), copy_if(), copy_backward(), reverse_copy(), rotate_copy(), and unique_copy().

This lesson is part of theÂ course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, Unlimited Access

Copying Algorithms

An introduction to the 7 copying algorithms in the C++ standard library: copy(), copy_n(), copy_if(), copy_backward(), reverse_copy(), rotate_copy(), and unique_copy().

This lesson is part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

• 124 Lessons
• 550+ Code Samples
• 96% Positive Reviews
• Regularly Updated
• Help and FAQ
Next Lesson

Removal Algorithms

An overview of the key C++ standard library algorithms for removing objects from containers. We cover remove(), remove_if(), remove_copy(), and remove_copy_if().