Skip to main content

std::move_backward() algorithm

// (1)
template< class BidirIt1, class BidirIt2 >
constexpr BidirIt2 move_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
  • (1) Moves the elements from the range [first; last), to another range ending at d_last.

    The elements are moved in reverse order (the last element is moved first), but their relative order is preserved.

    Undefined Behaviour

    The behavior is undefined if d_first is within [first; last). In this case, std::move may be used instead.

Parameters

first
last

The range of elements to move.

d_first

The beginning of the destination range.

Type requirements

BidirIt1
BidirIt2
LegacyBidirectionalIterator

Return value

Iterator in the destination range, pointing at the last element moved.

Complexity

Exactly last - first assignments.

Exceptions

(none)

Possible implementation

move_backward (1)
template<class BidirIt1, class BidirIt2>
BidirIt2 move_backward(BidirIt1 first, BidirIt1 last,
BidirIt2 d_last)
{
while (first != last)
*(--d_last) = std::move(*(--last));

return d_last;
}

Notes

When moving overlapping ranges:

  • std::move is appropriate when moving to the left (beginning of the destination range is outside the source range).
  • std::move_backward is appropriate when moving to the right (end of the destination range is outside the source range).

Examples

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>
#include <vector>

using container = std::vector<std::string>;

void print(std::string_view comment, const container& src, const container& dst = {})
{
auto prn = [](std::string_view name, const container& cont)
{
std::cout << name;
for (const auto &s : cont) { std::cout << (s.empty() ? "∙" : s.data()) << ' '; }
std::cout << '\n';
};
std::cout << comment << '\n';
prn("src: ", src);
if (dst.empty()) return;
prn("dst: ", dst);
}

int main()
{
container src {"foo", "bar", "baz"};
container dst {"qux", "quux", "quuz", "corge"};
print("Non-overlapping case; before move_backward:", src, dst);
std::move_backward(src.begin(), src.end(), dst.end());
print("After:", src, dst);

src = {"snap", "crackle", "pop", "lock", "drop"};
print("Overlapping case; before move_backward:", src);
std::move_backward(src.begin(), std::next(src.begin(), 3), src.end());
print("After:", src);
}
Output
Non-overlapping case; before move_backward:
src: foo bar baz
dst: qux quux quuz corge
After:
src: ∙ ∙ ∙
dst: qux foo bar baz
Overlapping case; before move_backward:
src: snap crackle pop lock drop
After:
src: ∙ ∙ snap crackle pop
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::move_backward() algorithm

// (1)
template< class BidirIt1, class BidirIt2 >
constexpr BidirIt2 move_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
  • (1) Moves the elements from the range [first; last), to another range ending at d_last.

    The elements are moved in reverse order (the last element is moved first), but their relative order is preserved.

    Undefined Behaviour

    The behavior is undefined if d_first is within [first; last). In this case, std::move may be used instead.

Parameters

first
last

The range of elements to move.

d_first

The beginning of the destination range.

Type requirements

BidirIt1
BidirIt2
LegacyBidirectionalIterator

Return value

Iterator in the destination range, pointing at the last element moved.

Complexity

Exactly last - first assignments.

Exceptions

(none)

Possible implementation

move_backward (1)
template<class BidirIt1, class BidirIt2>
BidirIt2 move_backward(BidirIt1 first, BidirIt1 last,
BidirIt2 d_last)
{
while (first != last)
*(--d_last) = std::move(*(--last));

return d_last;
}

Notes

When moving overlapping ranges:

  • std::move is appropriate when moving to the left (beginning of the destination range is outside the source range).
  • std::move_backward is appropriate when moving to the right (end of the destination range is outside the source range).

Examples

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>
#include <vector>

using container = std::vector<std::string>;

void print(std::string_view comment, const container& src, const container& dst = {})
{
auto prn = [](std::string_view name, const container& cont)
{
std::cout << name;
for (const auto &s : cont) { std::cout << (s.empty() ? "∙" : s.data()) << ' '; }
std::cout << '\n';
};
std::cout << comment << '\n';
prn("src: ", src);
if (dst.empty()) return;
prn("dst: ", dst);
}

int main()
{
container src {"foo", "bar", "baz"};
container dst {"qux", "quux", "quuz", "corge"};
print("Non-overlapping case; before move_backward:", src, dst);
std::move_backward(src.begin(), src.end(), dst.end());
print("After:", src, dst);

src = {"snap", "crackle", "pop", "lock", "drop"};
print("Overlapping case; before move_backward:", src);
std::move_backward(src.begin(), std::next(src.begin(), 3), src.end());
print("After:", src);
}
Output
Non-overlapping case; before move_backward:
src: foo bar baz
dst: qux quux quuz corge
After:
src: ∙ ∙ ∙
dst: qux foo bar baz
Overlapping case; before move_backward:
src: snap crackle pop lock drop
After:
src: ∙ ∙ snap crackle pop
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.