C++20stladvanced
std::ranges::move / move_backward (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Moves elements from one range to another, leaving source elements in a valid but unspecified state. `move_backward` moves in reverse order, useful when source and destination overlap.
Real-World Scenario
Transfer ownership of unique_ptr elements from a staging buffer to a final container.
Quick Snippet
snippet.cpp
#include <ranges>
#include <algorithm>
#include <vector>
#include <memory>
std::vector<std::unique_ptr<int>> src;
src.push_back(std::make_unique<int>(42));
std::vector<std::unique_ptr<int>> dst(src.size());
std::ranges::move(src, dst.begin());
// src[0] is now nullptr, dst[0] owns the intFull Example
ranges_move.cpp
// CodeNebula - C++20 Example: ranges::move, move_backward
// Compile: g++ -std=c++20 -Wall -Wextra -o example ranges_move.cpp
#include <iostream>
#include <ranges>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
int main() {
// ranges::move - move elements from source to destination
std::vector<std::string> source = {"alpha", "beta", "gamma", "delta", "epsilon"};
std::cout << "Before move - Source: ";
for (const auto& s : source) std::cout << "'" << s << "' ";
std::cout << "\n";
std::vector<std::string> dest(source.size());
std::ranges::move(source, dest.begin());
std::cout << "After move - Source: ";
for (const auto& s : source) std::cout << "'" << s << "' ";
std::cout << "\nAfter move - Dest: ";
for (const auto& s : dest) std::cout << "'" << s << "' ";
std::cout << "\n";
// ranges::move with integers (move == copy for trivial types)
std::vector<int> nums = {10, 20, 30, 40, 50};
std::vector<int> num_dest(nums.size());
auto [in_end, out_end] = std::ranges::move(nums, num_dest.begin());
std::cout << "\nMoved integers: ";
for (int n : num_dest) std::cout << n << " ";
std::cout << "\nInput fully consumed: " << std::boolalpha
<< (in_end == nums.end()) << "\n";
// ranges::move_backward - move elements backward
std::vector<std::string> data = {"one", "two", "three", "four", "five", "", "", ""};
std::ranges::move_backward(data.begin(), data.begin() + 5, data.end());
std::cout << "\nShifted right by 3: ";
for (const auto& s : data) std::cout << "'" << s << "' ";
std::cout << "\n";
// Move from a subrange
std::vector<std::string> words = {"hello", "beautiful", "world", "out", "there"};
std::vector<std::string> selected(2);
std::ranges::move(words.begin() + 1, words.begin() + 3, selected.begin());
std::cout << "\nMoved subrange: ";
for (const auto& s : selected) std::cout << "'" << s << "' ";
std::cout << "\n";
// Move unique_ptr (non-copyable types)
std::vector<std::unique_ptr<int>> ptrs;
ptrs.push_back(std::make_unique<int>(100));
ptrs.push_back(std::make_unique<int>(200));
ptrs.push_back(std::make_unique<int>(300));
std::vector<std::unique_ptr<int>> ptr_dest(ptrs.size());
std::ranges::move(ptrs, ptr_dest.begin());
std::cout << "\nMoved unique_ptrs: ";
for (const auto& p : ptr_dest)
if (p) std::cout << *p << " ";
std::cout << "\n";
return 0;
}
Run command
g++ -std=c++20 -Wall -Wextra -o example ranges_move.cpp