C++ Basics: Filter Records into a Growing Output Vector
Combine std::copy_if with std::back_inserter to retain selected values safely.
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 1Run the example
Save this as copy-if-back-inserter-demo.cpp:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
const std::vector<int> readings{-2, 0, 7, -1, 4};
std::vector<int> positive;
positive.reserve(readings.size());
std::copy_if(readings.begin(), readings.end(), std::back_inserter(positive),
[](int value) { return value > 0; });
std::cout << "Positive:";
for (int value : positive) std::cout << ' ' << value;
std::cout << "\nInput size: " << readings.size() << '\n';
}Compile and run it. The program runs only after compilation succeeds:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic copy-if-back-inserter-demo.cpp -o copy-if-back-inserter-demo &&
./copy-if-back-inserter-demoObserved output:
Positive: 7 4
Input size: 5Read the result
Only 7 and 4 satisfy the predicate, and their input order is retained. The source remains unchanged. back_inserter turns each output assignment into push_back, so the destination grows as matches are found.
Apply it carefully
reserve creates capacity, not elements. Writing through positive.begin() while its size is zero would be invalid, even after reserve. Use an insertion iterator or resize the output first and trim its unused suffix afterward. Keep source and destination storage separate here; appending to the same vector can invalidate the input iterators during reallocation.
The C++ working draft describes the relevant rules. This example builds in C++20 mode; the current working draft also documents later additions.
Clean up
Remove only the source and executable created here, then return to the starting directory:
rm -- copy-if-back-inserter-demo.cpp copy-if-back-inserter-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.