C++20
The largest C++ revision since C++11. Concepts, Ranges, Coroutines, and Modules — the "big four" — transform how modern C++ is written. Plus std::format, std::span, calendar types, and dozens of library additions.
Core Language
Named, composable constraints on template parameters. Replaces SFINAE for clean template interfaces.
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
void add(Addable auto a, Addable auto b) {
return a + b;
}Composable algorithms and lazy views over sequences. Replaces iterator-pair APIs with range-based ones.
#include <ranges>
#include <vector>
#include <iostream>
int main() {
std::vector v{1,2,3,4,5,6,7,8,9,10};
auto result = v
| std::views::filter([](int n){ return n % 2 == 0; })
| std::views::transform([](int n){ return n * n; })
| std::views::take(3);
for (int n : result) std::cout << n << ' '; // 4 16 36
}Stackless coroutines with co_await, co_yield, co_return. Foundation for async/await and generators.
#include <generator> // C++23 adds std::generator
// C++20: use library types like std::future or custom promise
// A generator-style coroutine with a library type
#include <cppcoro/generator.hpp>
cppcoro::generator<int> range(int from, int to) {
for (int i = from; i < to; ++i)
co_yield i;
}Replace #include with import/export. Faster builds, no macro pollution, proper encapsulation.
// math.ixx — module interface unit
export module math;
export int add(int a, int b) { return a + b; }
// main.cpp
import math;
import <iostream>; // or: import std; (C++23)
int main() {
std::cout << add(1, 2) << '\n';
}Operator <=> generates all comparison operators. Defaulting it gives a complete set of comparisons.
#include <compare>
struct Point {
int x, y;
auto operator<=>(const Point&) const = default; // generates all 6 operators
};
bool example(Point a, Point b) {
return a < b; // works!
}auto parameters in function declarations imply unconstrained templates. Combine with concepts.
// Equivalent to: template<typename T> void print(const T& v)
void print(const auto& v) {
std::cout << v << '\n';
}
// With concept constraint
void print_sortable(const std::sortable auto& v) { ... }Library
Type-safe, locale-aware string formatting. Python-style {} placeholders. The foundation for C++23 std::print.
#include <format>
#include <string>
int main() {
std::string s = std::format("Hello, {}! You are {} years old.", "Alice", 30);
// "Hello, Alice! You are 30 years old."
std::string hex = std::format("{:#010x}", 255);
// "0x000000ff"
}A non-owning view over a contiguous sequence. Pass arrays/vectors without copying. Replaces raw pointer + size pairs.
#include <span>
#include <vector>
void process(std::span<const int> data) {
for (int x : data) { /* ... */ }
}
int main() {
std::vector v{1,2,3,4,5};
process(v); // works
process({v.data(), 3}); // first 3 elements
int arr[] = {6,7,8};
process(arr); // C array — also works
}std::chrono gains calendar types (year_month_day), time zone support, and formatting.
#include <chrono>
#include <format>
using namespace std::chrono;
auto today = floor<days>(system_clock::now());
year_month_day ymd{today};
std::string s = std::format("Today: {}/{}/{}",
(int)ymd.year(), (unsigned)ymd.month(), (unsigned)ymd.day());std::atomic::wait, notify_one, notify_all — efficient wait without spinning. Also std::atomic_ref.
#include <atomic>
std::atomic<int> flag{0};
// Thread 1:
flag.wait(0); // block until flag != 0
// Thread 2:
flag.store(1);
flag.notify_one();