New C++20 features worth trying right now
Share
As of 2026, C++20 has been a stable standard for several years, and most modern compilers (GCC 11+, Clang 10+, MSVC 2019 16.11+) support it at a level sufficient for real-world projects. In this article, we’ll look at the C++20 features that are truly worth starting to use right now — they significantly simplify code, make it safer, and faster to write.
We won’t list everything — only the most practical and useful features for everyday work.
1. Concepts — the strongest new feature of C++20
Concepts allow you to constrain templates so that the compiler gives clear, human-readable errors instead of 10-page template monstrosities.
Example before C++20:
template<typename T>
void print(T value) {
std::cout << value << "\n";
}
After C++20 with concepts:
template<typename T>
concept Printable = requires(T t) {
std::cout << t;
};
void print(Printable auto value) {
std::cout << value << "\n";
}
Now if you pass a type that doesn’t support << — the error will be clear and at the user level.
Useful built-in concepts (C++20):
- std::integral
- std::floating_point
- std::regular
- std::equality_comparable
2. std::span — safe view over array/vector
Instead of passing pointer + size — just pass std::span.
#include <span>
void process(std::span<const int> data) {
for (int x : data) {
// safe, knows the size, no out-of-bounds risk
}
}
You can pass both std::vector and raw arrays without copying.
3. Ranges — revolution in collection processing
Ranges let you write chained operations like in functional languages, but with zero overhead.
Example:
#include <ranges>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto even = v | std::views::filter([](int x){ return x % 2 == 0; })
| std::views::transform([](int x){ return x * 10; });
for (int x : even) {
std::cout << x << " "; // 20 40 60 80 100
}
}
This is lazy evaluation — nothing is copied until iteration starts.
4. std::format — finally a proper format like in Python
#include <format> std::string message = std::format("Hello, {}! You are {} years old.", name, age);
Much safer and more convenient than std::stringstream or sprintf.
5. std::jthread — thread that joins itself
#include <thread>
std::jthread jt([]{
// this thread automatically finishes when leaving scope
// no explicit join() needed
});
Perfect for local background tasks.
6. std::source_location — exactly where to put logs
#include <source_location>
void log(const std::source_location& loc = std::source_location::current()) {
std::cout << loc.file_name() << ":" << loc.line() << " - ";
}
Automatically shows file and line of the call — no macros needed.

Summary — where to start right now
- Start using concepts in all your templates
- Replace raw arrays and pointers with std::span and std::array
- Switch to ranges instead of old loops
- Use std::format instead of stringstream
- Replace std::thread with std::jthread where detach is not needed
These 5 features already make code cleaner, safer, and faster to write in 2026. C++20 is not the future. It’s already the standard toolkit today.