📌 Please note that
- The idea of this overview is self education
- The main goal - keep it simple and short
- And it is primarily based on CppCon 2019 and Meeting C++ 2019 talks
- Modules
- Ranges
- Coroutines
- Concepts
- Concurrency
- Calendars and Timezones
- Initialization
- Lambda Expression
- Attributes
- Constant Expressions
- Bit Operations
- Source Location
- Spaceship Operator
- Abbreviated Function Templates
- Non-Type Template Parameters
span
- Feature-Test Macros
<version>
- Class Enums and
using
- Text Formatting
char8_t
- Math Constants
- Small Standard Library Additions
bind_front
- Strucutre Binding
auto
is now allowed in function parameters
auto Foo(auto param) { /* ... */ }
It is the same as
template<typename T> auto Foo(T param) { /* ... */ }
// or
auto Foo = [](T param) { /* ... */ }
Note:
concept auto
allowed anywhere thatauto
was allowed before
C++20 allows string literals for non-type template parameters.
template<auto& s>
void DoSomething() {
std::cout << s << std::endl;
}
int main() {
DoSomething<"C++20">();
}
Provides bounds-safe views for sequences of objects:
-
Does not own the data
-
Never allocates/deallocates
-
Very cheap to copy, recommended pass by value (similar to
string_view
) -
Does not support strides
-
Can be dynamic-sized and fixed-sized
constexpr size_t length = 10;
int data[length] = ...
span<int, length> a{data}; // fixed-size
span<int> b{data}; // dynamic-size
span<int> b{data, length}; // dynamic-size too
span<int, 20> a{data}; // compilation error
🔎 Example
Before:
void DoSomething(int* p, size_t size) {
std::sort(p, p + size);
for (size_t i = 0; i < size; ++i) {
p[i] += p[0];
}
}
// ...
std::vector<int> v;
DoSomething(v.data(), v.size());
int data[1024];
DoSomething(data, std::size(data));
Now:
void DoSomething(std::span<int> p) {
std2::sort(p);
for (int& v: p) {
v += p[0];
}
}
// ...
std::vector<int> v;
DoSomething(v);
int data[1024];
DoSomething(data);
Provides a simple and portable way to detect the presence of a compiler certain language and library features.
🔎 Example
#if __cpp_constexpr >= 201304
# define CONSTEXPR constexpr
#else
# define CONSTEXPR inline
#endif
CONSTEXPR int bar(unsigned i) {
#if __cpp_binary_literals
unsigned mask = 0b11000000;
#else
unsigned mask = 0xC0;
#endif
// ...
}
🔗 Additional Links
Supplies implementation-dependent information about the standard library:
- Version number
- Release date
- Copyright notice
- Additional implementation-defined information
- Include the library feature-test macros
🔎 Example
Before
enum class RgbColor { Red, Green, Blue };
std::string_view ColorToString(const Color color) {
switch (color) {
case RgbColor::Red: return "Red";
case RgbColor::Green: return "Green";
case RgbColor::Blue: return "Blue";
}
}
The necessary repetition of the enum class
name reduces legibility by introducing noise in contexts where said name is obvious.
Now
std::string_view ColorToString(const Color color) {
switch (color) {
using enum RgbColor; // introduce the enumerator identifiers into the local scope
case Red: return "Red";
case Green: return "Green";
case Blue: return "Blue";
}
}
std::format
provides a fast, simple and safe alternative to C stdio and C++ iostreams with pythonic string syntax.
std::cout << std::format("Hello, {}!", "world");
>_ Hello, world!
char8_t
is a new fundamental type to capture UTF-8 data that
-
Never aliases with other types because it is a distinct type
cout << std::boolalpha << is_same_v<char, char8_t> << ' ' << is_same_v<unsigned char, char8_t>;
>_ false false
-
Is always unsigned
-
Has the same size and alignment as
char
andsigned char
cout << sizeof(char) << " == " << sizeof(signed char) << " == " << sizeof(char8_t);
>_ 1 == 1 == 1
-
Can be overloaded upon
void print(std::u8string_view data); void print(std::string_view data); process("Hello, World!"); process(u8"Hello, 🌎!");
Following mathematical constant are defined:
e
,log2e
,log10e
pi
,inv_pi
,inv_sqrtpi
ln2
,ln10
sqrt2
,sqrt3
,inv_sqrt3
egamma
phi
🔗 Additional Links
starts_with
andends_with
forbasic_string
/basic_string_view
contains
for associative containersremove
,remove_if
, andunique
methods forlist
andforward_list
now returnsize_type
(number of removed elements) insted ofvoid
erase
anderase_if
algorithms equivalent toc.erase(std::remove_if(c.begin(), c.end(), pred), c.end());
nowshift_left
andshift_right
added to<algorithm>
midpoint
to calculates the midpoint of two numbers
bind_front
function is designed to bound first arguments of the function to some callable wrapper.
In other worlds
bind_front(f, bound_args...)(call_args...)
is equivalent to
std::invoke(f, bound_args..., call_args....)
🔎 Example
struct Strategy {
double calculate(double discount, double price) {
return price - ((discount / 100) * price);
}
};
unique_ptr<Strategy> CreateStrategy() {
return make_unique<Strategy>();
}
int main() {
auto apply20PercentDiscount = bind_front(&Strategy::calculate, CreateStrategy(), 20);
cout << apply20PercentDiscount(100);
}
>_ 80
struct Result {
bool status;
std::string data;
};
Result Process();
int main()
{
auto [ok, data] = Process();
static [ok, data] = Process(); // ok in C++20
thread_local [ok, data] = Process(); // ok in C++20
auto success = [ok] { return ok == true; } // ok in C++20
}