New keywords: char8_t
, co_await
, co_return
, co_yield
, concept
, consteval
, constinit
, import*
, module*
, requires
*
identifiers with a special meaning
Constrains on the template parameters and meaningful compiler messages in case on an error. Can also reduce the compilation time.
template <class T>
concept SignedIntegral = std::is_integral_v<T> && std::is_signed_v<T>;
template <SignedIntegral T> // no SFINAE here!
void signedIntsOnly(T val) { }
The replacement of the header files! With modules you can divide your program into logical parts.
import helloworld; // contains the hello() function
int main() {
hello(); // imported from the “helloworld” module!
}
Functions that can suspend their execution and can be resumed later, also asynchronously. They are associated with a promise object and might be allocated on the heap. C++20 gives language support. Use libs like cppcoro for full functionality (generators objects).
generator<int> iota(int n = 0) {
while (true)
co_yield n++;
}
New three-way comparison operator <=>
.
The expression a <=> b
returns an object such that
(a <=> b) < 0 if a < b
(a <=> b) > 0 if a > b
(a <=> b) == 0 if a and b are equal/equivalent.
and overloading:
R operator<=>(T,T);
where R can be: std::strong_ordering
std::weak_ordering
and std::partial_ordering
Explicit member names in the initializer expression:
struct S { int a; int b; int c; };
S test {.a = 1, .b = 10, .c = 2};
Create another variable in the scope of the range-based for loop:
for (int i = 0; const auto& x : get_collection()) {
doSomething(x, i);
++i;
}
Separate type for UTF-8 character representation, the underlying type is unsigned char
, but they are both distinct. The Library also defines now std::u8string
.
[[likely]]
- guides the compiler about more likely code path
[[unlikely]]
- guides the compiler about uncommon code path
[[no_unique_address]]
- useful for optimisations, like EBO
[[nodiscard]]
for constructors – allows us to declare the constructor with the attribute. Useful for ctors with side effects, or RAII.
[[nodiscard("with message")]]
– provide extra info
[[nodiscard]]
is also applied in many places in the Standard Library
Structured bindings since C++20 are more like regular variables, you can apply static
, thread_storage
or capture in a lambda.
Before C++20 only integral types, enums, pointer and reference types could be used in non-type template parameters. In C++20 it’s extended to classes that are Literal Types and have “structural equality”.
struct S { int i; };
template <S par> int foo() { return par.i + 10; }
auto result = foo<S{42}>();
Cleaner way to express if a constructor or a conversion function should be explicit. Useful for wrapper classes. Reduces the code duplication and SFINAE.
explicit(!is_convertible_v<T, int>) ...
constexpr is more relaxed you can use it for union, try and catch, dynamic_cast
, memory allocations, typeid
. The update allows us to create constexpr std::vector
and std::string
(also part of C++ Standard Library changes)! There are also constexpr algorithms like std::sort
, std::rotate
, std::reverse
and many more.
A new keyword that specifies an immediate function – functions that produce constant values, at compile time only. In contrast to constexpr functions, they cannot be called at runtime.
consteval int add(int a, int b) { return a+b; }
constexpr int r = add(100, 300);
Applied on variables with static or thread storage duration, ensures that the variable is initialized at compile-time. Solves the problem of static order initialisation fiasco for non-dynamic initialisation. Later the value of the variable can change.
A radical change how we work with collections! Rather than use two iterators, we can work with a sequence represented by a single object.
std::vector v { 2, 8, 4, 1, 9, 3, 7, 5, 4 };
std::ranges::sort(v);
for (auto& i: v | ranges:view::reverse) cout << i;
With Ranges we also get new algorithms, views and adapters
Python like formatting library in the Standard Library!
auto s = std::format("{:-^5}, {:-<5}", 7, 9);
s
has a value of „--7--, 9----” centred, and then left aligned.
Also supports the Chrono library and can print dates
Heavily updated with Calendar and Timezones.
auto now = system_clock::now();
auto cy = year_month_day{floor<days>(now)}.year();
cout << "The current year is " << cy << '\n';
Additionally we have updates like explicit file_clock
, clock_cast
(time point conversion) and many other enhancements.
jthread
- automatically joins on destruction. Stop tokens allows more control over the thread execution.
More atomics: floats, shared_ptr
, weak_ptr
, atomic_ref
Latches, semaphores and barriers – new synchronisation primitives
A on owning contiguous sequence of elements. Unlike string_view
, span is mutable and can change the elements that it points to.
vector<int> vec = {1, 2, 3, 4};
span<int> spanVec (vec);
for(auto && v : spanVec) v *= v;
typename
optional in more placesusing enum
–less typing for long enum class
namesvolatile
where it has no obvious meaning.std::bind_front()
- replacement for std::bind()
std::bit_cast()
and bit operationsstd::lerp()
and std::midpoint()
, Math constantsstd::source_location()
– get file/line pos without macros<version>
headererase/erase_if
non-member functions for most of containers!