Skip to content
C++ Basics: Split Records with partition_copy

C++ Basics: Split Records with partition_copy

November 3, 2026

Copy passing and failing records into separate vectors while keeping their original relative order.

Prepare a scratch directory

Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable compiler and standard-library development headers, with g++ on PATH. You also need Bash, a text editor, and the mktemp, rm, and rmdir utilities. No third-party library is required.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1

Run the example

Save this as partition-copy-records-demo.cpp:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

struct CheckResult {
    std::string name;
    bool passed;
};

int main() {
    const std::vector<CheckResult> checks{
        {"compile", true}, {"format", false},
        {"unit-tests", true}, {"links", false}
    };
    std::vector<CheckResult> passing_checks;
    std::vector<CheckResult> failing_checks;
    std::partition_copy(checks.begin(), checks.end(),
                        std::back_inserter(passing_checks),
                        std::back_inserter(failing_checks),
                        [](const CheckResult& result) { return result.passed; });
    std::cout << "Passing:";
    for (const auto& result : passing_checks) {
        std::cout << ' ' << result.name;
    }
    std::cout << '\n' << "Failing:";
    for (const auto& result : failing_checks) {
        std::cout << ' ' << result.name;
    }
    std::cout << '\n' << "Original count: " << checks.size() << '\n';
}

Compile and run it. The second command runs only after compilation succeeds:

g++ -std=c++20 -Wall -Wextra -Werror -pedantic partition-copy-records-demo.cpp -o partition-copy-records-demo &&
./partition-copy-records-demo

Observed output:

Passing: compile unit-tests
Failing: format links
Original count: 4

Read the result

compile and unit-tests go to the true destination; format and links go to the false destination. Each output preserves the input order of its selected records. The original vector is unchanged because this algorithm copies rather than rearranges the input.

Apply it carefully

Keep both destinations separate from the input and from each other. Output inserters grow the vectors as needed; raw begin iterators into empty vectors would not. The predicate should inspect records without modifying them. Copying strings has a cost, so consider in-place partitioning only when modifying the source and its order is acceptable.

The C++ working draft describes the relevant library rules. This example uses only C++20 facilities, even though the linked draft also documents newer additions.

Clean up

Remove only the source and executable created here, then remove the empty practice directory:

rm -- partition-copy-records-demo.cpp partition-copy-records-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directory

If the directory is not empty, inspect its remaining contents before removing anything else.

Acknowledgements

This post was created with assistance from AI.

Last updated on