C++ Basics: Handle Empty Ranges Before Reading Minima and Maxima
Check the iterators returned by minmax_element before dereferencing an empty result.
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 minmax-element-empty-range-demo.cpp:
#include <algorithm>
#include <iostream>
#include <vector>
void print_extremes(const std::vector<int>& values) {
const auto extremes = std::minmax_element(values.begin(), values.end());
if (extremes.first == values.end()) {
std::cout << "No readings\n";
return;
}
std::cout << "Minimum: " << *extremes.first
<< ", maximum: " << *extremes.second << '\n';
std::cout << "Indices: " << (extremes.first - values.begin())
<< ' ' << (extremes.second - values.begin()) << '\n';
}
int main() {
print_extremes({8, 3, 8, 3});
print_extremes({});
}Compile and run it. The second command runs only after compilation succeeds:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic minmax-element-empty-range-demo.cpp -o minmax-element-empty-range-demo &&
./minmax-element-empty-range-demoObserved output:
Minimum: 3, maximum: 8
Indices: 1 2
No readingsRead the result
The values are 3 and 8. The minimum iterator selects the first equal minimum, at index one; the maximum iterator selects the last equal maximum, at index two. Empty input returns end iterators, so the function prints a message without dereferencing either one.
Apply it carefully
Keep the source alive and avoid operations that invalidate its iterators before reading the results. This example uses integer ordering; a custom comparator must provide a strict weak ordering. If only the values matter, copy them while the iterators are valid. Never treat end as an element.
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 -- minmax-element-empty-range-demo.cpp minmax-element-empty-range-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.