Article by Ayman Alheraki on January 11 2026 10:33 AM
C++23, as part of the C++20 roadmap, brings several exciting improvements to the Standard Template Library (STL), enhancing both its performance and usability. The C++ Standards Committee continues to refine and expand the capabilities of STL to make programming more intuitive, efficient, and expressive. This article will highlight the major STL improvements in C++23 with examples.
C++23 introduces several improvements and new adaptors to the range library, introduced in C++20, making it even more versatile. The range library provides a powerful way to manipulate collections and sequences in a functional programming style.
views::chunk: Divides a range into smaller chunks of a specified size.
views::adjacent: Allows grouping adjacent elements into tuples of a specified size.
views::chunk
int main() { std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8};
for (auto chunk : numbers | std::views::chunk(3)) { for (auto n : chunk) { std::cout << n << " "; } std::cout << '\n'; }}Output:
1 2 3 4 5 6 7 8views::adjacent Example:
int main() { std::vector<int> numbers = {1, 2, 3, 4, 5};
for (auto [a, b] : numbers | std::views::adjacent<2>()) { std::cout << a << ", " << b << '\n'; }}Output:
1, 22, 33, 44, 5std::expected<T, E>One of the most anticipated additions to C++23 is the introduction of std::expected. This template class is similar to std::optional but with an explicit way to handle errors. Instead of exceptions or return codes, std::expected provides a more structured way to deal with potential failures, where T represents the success value and E represents the error value.
std::expected<int, std::string> divide(int a, int b) { if (b == 0) { return std::unexpected("Division by zero"); } return a / b;}
int main() { auto result = divide(10, 0);
if (result.has_value()) { std::cout << "Result: " << result.value() << '\n'; } else { std::cout << "Error: " << result.error() << '\n'; }}Output:
Error: Division by zeroC++23 includes various improvements for handling strings and formatting, building on the facilities introduced in C++20.
std::format with Ranges: std::format, introduced in C++20, now supports formatting entire ranges. This allows for a concise way to output entire collections in a custom format.
std::string improvements: Better integration with ranges and more efficient operations are included.
std::format with Ranges
int main() { std::vector<int> numbers = {1, 2, 3, 4, 5}; std::cout << std::format("Numbers: [{}]\n", std::views::all(numbers));}Output:
Numbers: [1, 2, 3, 4, 5]C++23 introduces several optimizations and feature enhancements in the STL containers, making them faster and more flexible.
std::flat_map and std::flat_set: These new containers are cache-friendly, combining the best aspects of std::map and std::set while storing the elements contiguously in memory.
Improved std::vector and std::list: Performance improvements, especially in operations like emplace_back and insert.
std::flat_map
int main() { std::flat_map<int, std::string> map = {{1, "one"}, {2, "two"}, {3, "three"}};
for (const auto& [key, value] : map) { std::cout << key << ": " << value << '\n'; }}std::span EnhancementsC++23 further extends the utility of std::span, which provides a non-owning view over a sequence of data. This is useful for passing arrays or parts of arrays around without copying.
void print_span(std::span<int> s) { for (int val : s) { std::cout << val << " "; } std::cout << '\n';}
int main() { int arr[] = {1, 2, 3, 4, 5}; std::span<int> sp(arr); print_span(sp);}Output:
1 2 3 4 5std::move_only_function: A new addition to the function object family, allowing for move-only callable objects. This will be beneficial for scenarios where functions or lambdas need to be passed around but are move-only.
std::stacktrace: Simplifies debugging by providing an API to capture and output the current stack trace, which can be extremely helpful for error handling in large systems.
C++23 continues the language's tradition of refining and expanding the Standard Template Library to meet modern programming needs. From the powerful new range adaptors to enhanced error handling via std::expected, C++23 makes C++ programming even more flexible and efficient. Developers working with modern C++ will find these features a valuable addition to their toolkit, allowing them to write cleaner, more expressive code while improving performance.
These improvements solidify C++’s position as a versatile and high-performance programming language in the modern software development landscape.