0% found this document useful (0 votes)
185 views62 pages

Modern C++ 11-20

C++ 11/14/17/20 features

Uploaded by

Tamás Benyács
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
185 views62 pages

Modern C++ 11-20

C++ 11/14/17/20 features

Uploaded by

Tamás Benyács
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 62
2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, C++20/17/14/11 Overview C++20 includes the following new language features: coroutines concepts, designated initializers template syntax for lambdas range-based for loop with initializer {likely]] and {{unlikely]] attributes deprecate implicit capture of this lass types in noi constexpr virtual functions explicit(bool) immediate functions 2 template parameters using enum, lambda capture of parameter pack char8 t constinit C++20 includes the following new library features concepts library synchronized buffered outputstream math constants stdzis constant evaluated std:make shared supports arrays starts with and ends with on strings check if associative container has element stdzbit cast std:midpoint std:to_array C++17 includes the following new language features: template argument deduction for class templates auto ye template parameters wi folding expressions new rules for auto deduction from braced: hitps:igithub.com/AnthonyCalandraimodem-cpp-featureststdmove ‘vee 2024.09.08. 17.00 Anthony Calandrafmodernppfealures:Achealsheot of modern C++ language and ibrary feature. © constexpr lambda * lambda capture this by value * inline variables * nested namespaces * structured bindings © selection statements with initializer © constexpr if © utf-8 character literals © direct-list-initialization of enums © [[fallthrough]], [Inodiscard]], ([maybe_unused]] attributes * _has include * class template argument deduction C+#17 includes the following new library features © std:variant * std:optional © stdian) © std:string_ view © stdsinvoke © std:apply © stdifilesystem © std:byte © splici * parallel algorithms © std:sample © stdiclamp for maps and sets © std:reduce © prefix sum algorithms © ged and lem © std:not_fn © string conversion to/from numbers C++14 includes the following new language features: © binary literals © generic lambda expressions © lambda capture initializers * return type deduction © decltype(auto) * relaxing constraints on constexpr functions © variable templates [[deprecated]} attribute hitps:igithub.com/AnthonyCalandraimodem-cpp-featureststdmove 2ie2 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, C++14 includes the following new library features © user-defined literals for standard library types * compile-time integer sequences © std:make_unique C++11 includes the following new language features: * move semantics * variadic templates * rvalue references * forwarding references itializer lists © static asset * auto * lambda expressions * decltype © type aliases + nullptr © stron © attributes * constexpr * delegating constructors © user-defined literals © explicit virtual overrides © final specifier © default functions * deleted functions * range-based for loops © special member functions for move semantics ® converting constructors © explicit conversion functions * inline-namespaces © non-static data member initializers © right angle brackets © ref-qualified member functions © trailing return types © noexcept specifier © char32_t and char16_t raw string literals C+#11 includes the following new library features: © std:move hitpsigithub.com/AnthonyCalandralmodem-cpp-featureststdmove sie2 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, © std::forward © type traits © smart pointers * std:chrono © tuples * stdstie © std:array * unordered containers © std:make shared © stdiref * memory model © stduasync * std:begin/end C++20 Language Features Coroutines Coroutines are special functions that can have their execution suspended and resumed. To define a coroutine, the co_return, co_await , or co_yield keywords must be present in the function's body. C++20's coroutines are stackless; unless optimized out by the compiler, their state is allocated on the heap. An example of a coroutine is a generator function, which yields (i. generates) a value at each invocation: generatorcint> range(int start, int end) { @ wile (start < end) { co-yield start; startess // Implicit co_return at the end of this function: J/ co_return; for (int n : range(@, 1€)) { std::cout << n << std::endl; The above range generator function generates values starting at start until end (exclusive), with each iteration step yielding the current value stored in start . The generator maintains its state across each invocation of range (in this case, the invocation is for each iteration in the for ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 4162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, loop). co_yield takes the given expression, yields (i. returns) its value, and suspends the coroutine at that point. Upon resuming, execution continues after the co_yield Another example of a coroutine is a task, which is an asynchronous computation that is executed when the task is awaited: taskcvoid> echo(socket s) { e for (53) ¢ auto data = co_await s.async_read(); co_await async_write(s, data); y // Implicit co_return at the end of this function: J/ co_return; In this example, the co_await keyword is introduced. This keyword takes an expression and suspends execution if the thing you're awaiting on (in this case, the read or write) is not ready, otherwise you continue execution. (Note that under the hood, co_yield uses co_await .) Using a task to lazily evaluate a value: taskcint> calculate_meaning_of_life() { a co_return 42; auto meaning_of_life = calculate_meaning_of_life(); Wve co_await meaning of_life; // == 42 Note: While these examples illustrate how to use coroutines at a basic level, there is lots more going on when the code is compiled. These examples are not meant to be complete coverage of C++20's coroutines. Since the generator and task classes are not provided by the standard library yet, | used the cppcoro library to compile these examples. Concepts Concepts are named compile-time predicates which constrain types. They take the following form: template < template-parameter-list > oa concept concept-name = constraint-expression; where constraint-expression evaluates to a constexpr Boolean. Constraints should model semantic requirements, such as whether a type is a numeric or hashable. A compiler error results if a given type does not satisfy the concept it's bound by (ie. constraint-expression returns false ) Because constraints are evaluated at compile-time, they can provide more meaningful error messages and runtime safety. ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave si62 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, // “T is not Limited by any constraints. oe tenplate concept always_satisfied // Limit “T to integrals. tenplate trues concept integral = std::is_integral_v; // Limit “T to both the “integral” constraint and signedness template concept signed_integral = integral && std::is_signed_v; // Limit “T to both the “integral” constraint and the negation of the ~signed_integra ‘template concept unsigned_integral = integral && !signed_integral; There are a variety of syntactic forms for enforcing concepts: ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave eie2 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, // Forms for function parameters: // °T is a constrained type template parameter. template void #(T v); // °T is a constrained type template parameter. template requires my_concept void #(T v); // °T is a constrained type template parameter. template void #(T v) requires my_concept; // -w is a constrained deduced parameter. void #(my_concept auto v); // ‘vis a constrained non-type template parameter. tenplate void 6()5 // Forms for auto-deduced variables. // foo” is a constrained auto-deduced value. my_concept auto foo : // Forms for lambdas: 1] “T° is a constrained type tenplate parameter. auto f = [] (T v) { We Ms /] “is a constrained type tenplate parameter. auto f = []étypenane T> requires my_concept (T v MT vee Bb /] “Tis a constrained type template parameter. auto f = []étypenane T> (T v) requires ny_concept Mises h /] “vis a constrained deduced parameter. auto # = [](ay_concept auto v) { Me b // “Ww is a constrained non-type template parameter. auto g = [] () { We hs The requires keyword is used either to start a requires clause ora requires expression: -ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 82 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, template e requires ay_concept // “requires” clause. void #(T)3 template concept callable = requires (T f) { £()3 }s // “requires” expression. template requires requires (T x) { x + x; } // “requires” clause and expression on same line. T add(T a, Tb) { return a +b; Note that the parameter list in a requires expression is optional. Each requirement in a requires expression are one of the following: * Simple requirements - asserts that the given expression is valid. template a concept callable = requires (T #) { £()3 35 © Type requirements - denoted by the typenane keyword followed by a type name, asserts that the given type name is valid ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave ice 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, struct foo { oe int F005 oH struct bar { using value = int; value data; ui struct baz { using value value data; oH int; // Using SFINAE, enable if “T” is a “baz ‘template >> ‘template using Ref = T&; template concept C = requires { // Requirements on type °T typename T::value; // A) has an inner menber named “value typename S; // B) must have a valid class template specialization for typename Ref; // C) must be a valid alias template substitution a template void g(T a); @(Foo(}); // ERROR: e(bar(}); // ERO e(baz{}); // PASS. Fails requirement A. Fails requirement B. * Compound requirements - an expression in braces followed by a trailing return type or type constraint. template a concept ¢ = requires(T x) { {ix} => st {xa} => st it 1} > st oa convertible_to; // the type of the expression “*x” i ame_as; // the expression “x + 1° satisfies “std: :same_as; // the type of the expression “x * 1° is converti * Nested requirements - denoted by the requires keyword, specify additional constraints (such as those on local parameter arguments). ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 9i62 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, template a concept C = requires(T x) { requires std::same_as; See also: concepts library. Designated initializers C-style designated initializer syntax. Any member fields that are not explicitly listed in the designated initializer list are default-initialized, struct A { ea int x; int y5 int z 123; Aa{.xe=d, .2 = 2); // ax ay ® az Template syntax for lambdas Use familiar template syntax in lambda expressions. auto f = [](std::vector v) { a Wise a Range-based for loop with initializer This feature simplifies common code patterns, helps keep scopes tight, and offers an elegant solution to a common lifetime problem. for (auto v = std::vector{1, 2, 3}3 auto& e : v) { oa std::cout << @5 } // prints "123" [[likely]] and [[unlikely]] attributes Provides a hint to the optimizer that the labelled statement has a high probability of being executed. hitps:igithub.com/AnthonyCalandraimodem-cpp-featureststdmove 10162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, switch (n) { oO case 1 MW. break; [[likely]] case 2: // n == 2 is considered to be arbitrarily more Move // Likely than any other value of n break; } If one of the likely/unlikely attributes appears after the right parenthesis of an if-statement, it indicates that the branch is likely/unlikely to have its substatement (body) executed. int random = get_random_nunber_between_x_and_y(®, 3)5 o if (random > ®) [[1ikely]] { // body of if statement Moses > It can also be applied to the substatement (body) of an iteration statement. while (unlikely truthy condition) [[unlikely]] { oe // body of while statement WT vee Deprecate implicit capture of this Implicitly capturing this ina lambda capture using [=] is now deprecated; prefer capturing explicitly using [=, this] or [=, *this] . struct int_value { a int n= @; auto getter_fn() { 1) BAD: 11 return [=]() { return nz )3 11 600d: return [=, *this]() { return n; }; Class types in non-type template parameters Classes can now be used in non-type template parameters, Objects passed in as template arguments have the type const , where T is the type of the object, and has static storage ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 82 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, duration. struct foo ( a foo() = default; constexpr foo(int) {} hb ‘template auto get_foo() { return £3 get_foo(); // uses implicit constructor get_foo(); constexpr virtual functions Virtual functions can now be constexpr and evaluated at compile-time. constexpr virtual functions can override non- constexpr virtual functions and vice-versa. struct x1 a virtual int f() const = @: b struct X2: public X1 { constexpr virtual int f() const { return 2; } oe struct X3: public x2 { virtual int f() const { return 3; } h struct x4: public x3 { constexpr virtual int () const { return 4; } ui constexpr x4 x43 x4.F()5 // == 4 explicit(bool) Conditionally select at compile-time whether a constructor is made explicit or not. explicit(true) is the same as specifying explicit ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 12162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, struct foo { e // Specify non-integral types (strings, floats, etc.) require explicit construction. template explicit(!std::is_integral_v) fo0(T) (} b foo a = 123; // Ok foo b = "123"; // ERROR: explicit constructor is not a candidate (explicit specifier e foo c {123}; // Ok Immediate functions Similar to constexpr functions, but functions with a consteval specifier must produce a constant. These are called immediate functions consteval int sqr(int n) { e return n * nj constexpr int r = sqr(108); // ok int x = 1005 sqr(x)3 // ERROR: the value of ‘x' is not usable in a constant expression // 0K if ~sqr” were a “constexpr” function int r2 using enum Bring an enum's members into scope to improve readability. Before: enun class rgba_color_channel { red, green, blue, alpha }; a st string_view to_string(rgba_color_channel channel) { switch (channel) { case rgba_color_channel: case rgba_color_channel: return return red"; "green"; "blue"; : return “alpha”; case rgba_color_channel: return case rgba_color_channel: After: ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 13162 2026.03, 05.17.00 ‘AnthonyCalandramodem-cpp-features A chealshool of modern C++ language and brary features enum class rgba_color_channel { red, green, blue, alpha }; oO st string_view to_string(rgba_color_channel my_channel) { switch (my channel) { using enum rgba_color_channel; case red: return case green: return “green”; case blue: return “blue”; case alpha: return “alpha”; red Lambda capture of parameter pack Capture parameter packs by value: template a auto f(Args8&... args){ 11 BY VALUE: return [...args = std::forwardcArgs>(args)] { u. ub Capture parameter packs by reference: template a auto f(Args@&... args){ // BY REFERENCE: return [&...args = std::forward(args)] { MD vee b char8_t Provides a standard type for representing UTF-8 strings. char8_t utf8_str[] = u8"\ue123"; e constinit The constinit specifier requires that a variable must be initialized at compile-time. ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave aie 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, const char* g() { return “dynamic initialization"; } oO constexpr const char* (bool p) { return p ? “constant initializer" : g()3 } constinit const chart ¢ = f(true); // 0K constinit const char* d = f(false); // ERROR: ~g’ is not constexpr, so “d° cannot be e C++20 Library Features Concepts library Concepts are also provided by the standard library for building more complicated concepts. Some of these include Core language concepts: © sane_as ~ specifies two types are the same. © derived_fron - specifies that a type is derived from another type * convertible_to - specifies that a type is implicitly convertible to another type. * conmon_with ~ specifies that two types share a common type. * integral - specifies that a type is an integral type. © default_constructible - specifies that an object of a type can be default-constructed, Comparison concepts: * boolean - specifies that a type can be used in Boolean contexts. © equality_conparable ~ specifies that operator== is an equivalence relation. Object concepts: * movable - specifies that an object of a type can be moved and swapped. * copyable - specifies that an object of a type can be copied, moved, and swapped. © semiregular - specifies that an object of a type can be copied, moved, swapped, and default constructed. © regular ~ specifies that a type is regular, that is, itis both semiregular and equality_conparable . Callable concepts: * invocable ~ specifies that a callable type can be invoked with a given set of argument types. * predicate - specifies that a callable type is a Boolean predicate. See also: concepts. Synchronized buffered outputstream Buffers output operations for the wrapped output stream ensuring synchronization (i.e. no interleaving of output). ‘ntpsigthub.convAnthonyCalandraimodem- Example: using a dynamically-sized span to print integers from various containers. void print_ints(std::spancconst int> ints) { e for (const auto n : ints) { std::cout << n << std::endl; ector{ 1, 2, 3 })5 iarray{ 1, 2, 3, 4, 5 })5 int a[20] = (0 35 print_ints(a) If ete. Example: a statically-sized span will fail to compile for containers that don't match the extent of the span ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 6162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, void print_three_ints(std::spancconst int, 3> ints) { oO for (const auton : ints) { std::cout << n << std::endl; print_three_ints(std::vector{ 1, 2, 3 })3 // ERROR print_three_ints(std::array{ 1, 2, 3, 4, 5 }); // ERROR int a[10] = { @ }; print_three_ints(a); // ERROR std::arraycint, 3> b= (1, 2,335 print_three_ints(b); // 0k // You can construct a span manually if required: std::vector ¢{ 1, 2, 3 }5 print_three_ints(std::spancconst int, 3>{ c.data(), 3 }); // OK: set pointer and lengt print_three_ints(std::spancconst int, 3>{ c.cbegin(), c.cend() })3 // OK: use iterator Bit operations C+#20 provides anew header which provides some bit operations including popcount. std::popcount(@u); // @ e std::popcount (Iu); // 1 std::popcount(@b1111'@000u); // 4 Math constants Mathematical constants including PI, Euler's number, etc. defined in the header. is // 3.14159... a 5 1) 2.71828 st st numbers numbers std::is_constant_evaluated Predicate function which is truthy when it is called in a compile-time context. constexpr bool is_compile_time() { oa return std::is_constant_evaluated(); constexpr bool a = is compile time(); // true bool b = is_compile_time(); // false ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 782 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, std::make_shared supports arrays auto p = std::make_sharedcint[]>(5)3 // pointer to “int(5] a // OR auto p = std iake_shared(); // pointer to ~int[5]° starts_with and ends_with on strings Strings (and string views) now have the starts_with and ends_with member functions to check if a string starts or ends with the given string. std:isteing str = "foobar"; oe str.starts_with("foo"); // true str.ends_with("baz"); // false Check if associative container has element Associative containers such as sets and maps have a contains member function, which can be used instead of the “find and check end of iterator" idiom. std::mapcint, char> map {{1, ‘a"}, (2, ‘b'}}5 oa map.contains(2); // true map.contains(123); // false std::set set (1, 2, 3); set.contains(2); // true std:: it_cast A safer way to reinterpret an object from one type to another. 123.05 @ std: :bit_castcint>(f); float f int i std: idpoint Calculate the midpoint of two integers safely (without overflow). std::midpoint(1, 3); // std::to_array Converts the given array/“array-like" object to a. std: :array . ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 10162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, std::to_array("foo"); // returns “std::array° a std::to_arraycint>({1, 2, 3})3 // returns “std::arraycint, 3>° int af] = (1, 2, 3} std::to_array(a); // returns “st array° C++17 Language Features Template argument deduction for class templates Automatic template argument deduction much like how it's done for functions, but now including class constructors. template e struct MyContainer { T vals Mycontainer() + val} 0} Mycontainer(T val) : val{val) () Moves h MyContainer ¢1 {1}5 // OK MyContainercint> MyContainer ¢25 // OK MyContainer Declaring non-type template parameters with auto Following the deduction rules of auto , while respecting the non-type template parameter list of allowable types[*], template arguments can be deduced from the types of its arguments: template a struct my_integer_sequence { // Implementation here ... ub // explicitly pass type “int’ as template argument. auto seq = std::integer_sequencecint, @, 1, 2>()5 // Type is deduced to be ~int™. auto seq2 = my_integer_sequence<@, 1, 2>()5 *- For example, you cannot use a double as a template parameter type, which also makes this an invalid deduction using auto . Folding expressions A fold expression performs a fold of a template parameter pack over a binary operator. hitps:igithub. com/AnthonyCalandraimodem-cpp-featureststdmove 19162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, * An expression of the form (... op e) or (e op ...), where op isa fold-operator and e is an unexpanded parameter pack, are called unary folds. * An expression of the form (e1 op ... op e2) , where op are fold-operators, is called a binary fold. Either e1 or e2 is an unexpanded parameter pack, but not both. template a bool logicalAand(Args... args) { // Binary folding. return (true && ... && args); } bool b = true; bool& b2 = b; logicaland(b, 62, true); // == true ‘template a auto sum(Args... args) { // unary Folding. return ( + args); } sum(1.0, 2.0f, 3)3 // New rules for auto deduction from braced-init-list Changes to auto deduction when used with the uniform initialization syntax. Previously, auto x (3); deduces a std::initializer_listcint> , which now deduces to int . auto x1 (1, 2, 3}; // error: not a single element a auto x2 = (1, 2, 3)5 // x2 is std::initializer_listcint> auto x3 {3}; // x3 is int auto x8 {3.0}; // x4 is double constexpr lambda Compile-time lambdas using constexpr . auto identity = [](int n) constexpr { return nj}; a static_assert(identity(123) == 123); ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 20162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, constexpr auto add = [J(int x, int y) ¢ oe auto L = [=] { return x; }5 auto R = [=] { return y3 }5 return [=] { return L() + R()5 3s Ms static_assert(add(1, 2)() == 3); constexpr int addone(int n) ¢ a return [a] { return n +45 305 3 static_assert(addone(1) 2)3 Lambda capture this by value Capturing this ina lambda's environment was previously reference-only. An example of where this is problematic is asynchronous code using callbacks that require an object to be available, potentially past its lifetime, *this (C++17) will now make a copy of the current object, while this (C++11) continues to capture by reference. struct MyObj { e int value {123}; auto getValueCopy() ¢ return [this] { return values }3 > auto getValueRef() { return [this] { return value; }; > B My0b3 mos auto valueCopy = mo.getValueCopy(); auto valueRef = mo.getValueRef(); mmo.value = 3213 valuecopy(); // 123 valueRef()} // 321 Inline variables The inline specifier can be applied to variables as well as to functions. A variable declared inline has the same semantics as a function declared inline. -ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 21162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, // Disassembly example using compiler explorer. oO struct S$ { int x; }5 inline $ x1 = $(321); // mov esi, dword ptr [x1] // x1: slong 321 S x2 = S{123}; // mov eax, dword ptr [.L_ZZ4mainE2x2] // mov dword ptr [rbp - 8], eax Jf L_224mainE2x2: long 123 It can also be used to declare and define a static member variable, such that it does not need to be initialized in the source file. struct 5 { e SQ) : id{count++} {} ~8() { count--5 } int id; static inline int count{@}; // declare and initialize count to @ within the class ub Nested namespaces Using the namespace resolution operator to create nested namespace definitions, namespace A { e namespace B { namespace © ( int 45 y } y The code above can be written like this: 20 a namespace A: int 4; 3 Structured bindings A proposal for de-structuring initialization, that would allow writing auto [ x, y, 2] = expr; where the type of expr was a tuple-like object, whose elements would be bound to the variables x, y, and 2 (which this construct declares). Tuple-like objects include std::tuple, std::pair, std::array , and aggregate structures, ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 22162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, using Coordinate = std::paircint, int>; e Coordinate origin() { return Coordinate{@, @}; 3 const auto [ x, y ] = origin(); xj // == ys] =e st tring, int> mapping e unordered_map 1k(mx) ; if (v.empty()) v.push_back(val); } // vs. if (std::lock_guard 1k(mx); v-empty()) { Foo gadget(args); e switch (auto s = gadget.status()) { case OK: gadget.zip(); break; case Bad: throw BadFoo(s.message()); t Ji ws. switch (Foo gadget(args); auto s ~ gadget.status()) ¢ case 0K: gadget.zip(); break; case Bad: throw BadFoo(s.message()); constexpr if ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 262 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, Write code that is instantiated depending on a compile-time condition. ‘template constexpr bool isIntegral() { if constexpr (std::is_integral::value) { return true; } else { return false; , 3 static_assert(isIntegral() == true); static_assert(isIntegral() == true); static_assert(isIntegral() == false); struct $ (5 static_assert(istntegral() false); UTF-8 character literals A character literal that begins with us isa character literal of type char . The value of a UTF-8 character literal is equal to its ISO 10646 code point value. char x = u8'x's Direct list initialization of enums Enums can now be initialized using braced syntax. enum byte : unsigned char {}; byte b {0}; // OK byte c {-1}; // ERROR byte d = byte(1}; // 0K byte e = byte(256}; // ERROR [[fallthrough]], [[nodiscard]], [[maybe_unused]] attributes C+#17 introduces three new attributes: [[fallthrough]] , [[nodiscard]] and [[maybe_unused]] © [[falithrough]] indicates to the compiler that falling through in a switch statement is intended behavior. This attribute may only be used in a switch statement, and must be placed before the next case/default label. ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 24162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, switch (n) { e case 1: “ [[fallthrough]]; case 2: us break; case 3: Moves [[fallthrough]]; default: Wn © [[nodiscard}] issues a warning when either a function or class has this attribute and its return value is discarded [[nodiscard]] bool do_something() { oe return is success; // true for success, false for failure do_sonething(); // warning: ignoring return value of ‘bool do_sonething()’, // declared with attribute ‘nodiscard’ // Only issues a warning when “error_info” is returned by value. oa struct [[nodiscard]] error_info { uy % error_info do_something() { error_info ei; Wise return ei; do_sonething(); // warning: ignoring returned value of type “error_info", // declared with attribute ‘nodiscard” © [[maybe_unused]}] indicates to the compiler that a variable or parameter might be unused and is intended. void ny_callback(std::string msg, [[maybe_unused]] bool error) ( oa // Don*t care if ‘msg’ is an error message, just log it. Log (msg); 3 ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 25162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, —has_include __has_inelude (operand) operator may be used in #if and #elif expressions to check whether a header or source file ( operand ) is available for inclusion or not. One use case of this would be using two libraries that work the same way, using the backup/experimental one if the preferred one is not found on the system. wifdef _has_include oa # if _has_include() # include # — define have_optional 1 # elif _has_include() # include # — define have_optional 1 # — define experimental_optional # else it — define have_optional @ # endif Hendif It can also be used to include headers existing under different names or locations on various platforms, without knowing which platform the program is running on, OpenGL headers are a good example for this which are located in opengL\ directory on macOS and Gt\ on other platforms. #ifdef _has_include a # if _has_include() # include # include # elif _has_include() # include # include # else # error No suitable OpenGL headers found. endif endif Class template argument deduction Class template argument deduction (CTAD) allows the compiler to deduce template arguments from constructor arguments. vector v{ 1, 2, 3 }5 // deduces std::vectorcint> @ st auto Ick = std::lock_guard{ mtx }; // deduces to std rimutex mtx; lock_guard auto p = new std::pair{ 1.8, 2.0 }; // deduces to std::pair ntipsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 26162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, For user-defined types, deduction guides can be used to guide the compiler how to deduce template arguments if applicable: template @ struct container { container(T t) () template container(Iter beg, Iter end); oa // deduction guide template container(Iter b, Iter e) -> containerctypenane std: terator_traits: :value_type container a{ 7 }; // OK: deduces containercint> std::vector v{ 1.0, 2.0, 3.8 }; auto b = container{ v.begin(), v.end() }3 // OK: deduces container container c{ 5, 6 }5 // ERROR: std::iterator_traits::value_type is not a type C++17 Library Features std::variant The class template std::variant represents a type-safe union . An instance of std::variant at any given time holds a value of one of its alternative types (it's also possible for it to be valueless). std: std::getcint>(v); // std: :get(v); // v = 12.05 std: :get(v)3 // == 12.0 variantcint, double> v( 42 )3 @ 2 12 12.8 std::optional The class template std: :optional manages an optional contained value, i. a value that may or may not be present. A common use case for optional is the return value of a function that may fail ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 262 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, std: :optional create(bool b) { e if (b) { return "Godzilla"; } else { return (35 } 3 create(false).value_or(*empty")5 // = create(true).value(); // == “Godzilla” // optional-returning factory functions are usable as conditions of while and if if (auto str = create(true)) { Wives empty" std::any A type-safe container for single values of any type. stdirany x (5}3 a x.has_value() // true std: :any_cast(x) // Hany_cast(x) // std::string_view A non-owning reference to a string. Useful for providing an abstraction on top of strings (e.g. for parsing). // Regular strings. oO std::string_view cppstr {"foo"}; // Wide strings. std::wstring_view westr_v {L"baz"}; // Character arrays. char array[3] = {‘b', ‘a', ‘r'}s std::string_view array_v(array, std::size(array)); std::string str ("trim me"); a std::string view v {str}; v.renove_prefix(std: :min(v.find_ str; // == trim me" v5 // == “trim me" rst_not_of(" + vesize()))i std::invoke ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 2ai62 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, Invoke a Callable object with parameters. Examples of callable objects are std::function or lambdas; objects that can be called similarly to a regular function template @ class Proxy { callable c_; public Proxy(Callable c) : c_{ std::move(c) } {} template decltype(auto) operator()(Args&&... args) { Move return std:: , i nvoke(c_, std: :forward (args). const auto add = [](int x, int y) { return x + y5 }3 Proxy pt add 35 PCL, 2)5 // == 3 std::apply Invoke a Callable object with a tuple of arguments auto add = [](int x, int y) { a return x + ys std::apply(add, std rmake_tuple(1, 2); // std::filesystem The new std::filesysten library provides a standard way to manipulate files, directories, and paths in a filesystem, Here, a big file is copied to a temporary path if there is available space: const auto bigFilePath {"bigFileToCopy"}; a Af (std: filesystem: exists (bigFilePath)) { const auto bigFileSize (std: :filesyste std:: Filesystem: :path tmpPath {"/tmp"}; pace(tmpPath) available > bigFileSize) { std: : filesystem: :create_directory(tmpPath. append(“example")) ; std: filesystem: :copy_file(bigFilePath, tmpPath.append("newFile")); ‘ile_size(bigFilePath)}; ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 20162 2026.03, 05.17.00 ‘AnthonyCalandramodem-cpp-features A chealshool of modern C++ language and brary features std::byte The new std::byte type provides a standard way of representing data as a byte. Benefits of using std::byte over char or unsigned char is that it is not a character type, and is also not an arithmetic type; while the only operator overloads available are bitwise operations. std::byte a {0}; e std::byte b {OxFF}; int i = std::to_integercint>(b)3 // @xFF std::byte c= 2 & b; int j = std::to_integercint>(c); // @ Note that std::byte is simply an enum, and braced initialization of enums become possible thanks to direct-list-initialization of enums. Splicing for maps and sets Moving nodes and merging containers without the overhead of expensive copies, moves, or heap allocations/deallocations. Moving elements from one map to another: rimapcint, stringy sre ({1, “one"}, (2, “two"), (3, "buckle my shoe"); a std:imapcint, string> dst ({3, "three"}}5 dst.insert(src.extract(src.find(1))); // Cheap remove and insert of { 1, “one” } from dst.insert(src.extract(2)); // Cheap remove and insert of { 2, “two” } from “src” to // dst == ( (1, “one” }, (2, "two" }, (3, “three” } }5 Inserting an entire set: std::setcint> sre {1, 3, 5)5 e std::setcint> dst {2, 4, 5); dst.merge(sre); d/ sre == (5 } If dst == (1, 2, 3, 4, 5} Inserting elements which outlive the container: auto elementFactory() { e std: :set<...> 5 s.emplace(...)5 return s.extract(s.begin()); 3 s2.insert(elementFactory()); Changing the key of a map element: ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 0162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, std::mapcint, string> m {{1, “one"}, {2, “two"}, (3, "three"}}; oO auto e = m.extract(2); e.key() = 45 m.insert (std: :move(e)); //m=={{4, “one” }, { 3, “three” }, (4, “two” } } Parallel algorithms Many of the STL algorithms, such as the copy, find and sort methods, started to support the parallel execution policies: seq, par and par_unseq which translate to "sequentially”, "parallel" and "parallel unsequenced". std::vector longVector; a // Find elenent using parallel execution policy auto result1 = std::find(std::execution::par, std::begin(longVector), std::end(longVec // Sort elenents using sequential execution policy auto result2 = std::sort(std: :execution::seq, std::begin(longVector), std: :end(longvec std::sample Samples n elements in the given sequence (without replacement) where every element has an equal chance of being selected const std::string ALLOWED_CHARS = “abcdefghijlmnopqrstuvwxy2ABCOEFGHIIKLMNOPQRSTUVWKY CG) st string guid; // Sample 5 characters from ALLOWED_CHARS. st sample(ALLOWED_CHARS.begin(), ALLOWED_CHARS.end(), std: :back_inserter(guid), 5, std::mt19937{ std: :random_device{}() })5 cout << guid; // e.g. G1fW2 std::clamp Clamp given value between a lower and upper bound std: st st clamp (42, -1, 1)5 // = clamp(-42, -1, 1); // clamp(@, -1, 1); // // “std: clamp" also accepts a custom comparator: std::clamp(@, -1, 1, std::lesse>{}); // == @ std::reduce ntipsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 62 2024.09.08. 17.00 Anthony Calandrafmodernppfealures:Achealsheot of modern C++ language and ibrary feature. Fold over a given range of elements. Conceptually similar to. std: :accunulate , but std::reduce will perform the fold in parallel. Due to the fold being done in parallel, if you specify a binary operation, it is required to be associative and commutative. A given binary operation also should not change any element or invalidate any iterators within the given range The default binary operation is sta::plus with an initial value of 0. const std::arraycint, 3> a 1, 2, 3)5 std:sreduce(std::cbegin(a), std::cend(a)); // == 6 // Using a custom binary op: std:treduce(std: :cbegin(a), std:icend(a), 1, std: multiplies<>{}); // Additionally you can specify transformations for reducers: std::transform_reduce(std::cbegin(a), std::cend(a), @, std::plus<>{}, times_ten); //= const std::arraycint, 3> b( 1, 2, 3 }5 const auto product_times_ten = [](const auto a, const auto b) { return a * b * 10; }5 std: :transform_reduce(std: :cbegin(a), std::cend(a), std::cbegin(b), @, std: :plus<{}, Prefix sum algorithms Support for prefix sums (both inclusive and exclusive scans) along with transformations const std::arraycint, 3> a{ 1, 2, 3} @ cbegin(a), std::cend(a), “hh std::inclusive_scan(std: std: :ostream_iterator{ std::cout, plus<>{})3 // 13 6 std: sexelusive_scan(std::ebegin(a), std::cend(a), std: sostream_iteratorcint>{ std::cout, "" }, @ std::plus<>{}); // @ 13 const auto times_ten = [](const auto n) { return n * 10; }; std: :transform_inclusive_scan(std::cbegin(a), std::cend(a), std: sostream_iteratorcint>{ std::cout, "" }, std::plus<>{}, times_ten); // 10 3 ‘transform_exclusive_scan(sté::cbegin(a), std::cend(a), std: tostream_iteratorcint>{ std::cout, "* }, @, std::plus<>{), times ten); // @ 1 GCD and LCM Greatest common divisor (GCD) and least common multiple (LCM). ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 2162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, const int p = 93 e const int q = 3; std:igcd(p, 4)3 // std::lem(p, q)i // std::not_fn Utility function that returns the negation of the result of the given function. const std::ostream_iteratorcint> ostream_it( sti const auto is_even = [](const auto n) { return n % 2 = std::vectorcint> v{ ®, 1, 2, 3, 4 35 // Print all even numbers. std: :copy_if(std::cbegin(v), std::cend(v), ostrean_it, is_even); // 024 // Print all odd (not even) numbers. copy_if(std::cbegin(v), std::cend(v), ostrean_it, std::not_fn(is_even)); // 13 st String conversion to/from numbers. Convert integrals and floats to a string or vice-versa. Conversions are non-throwing, do not allocate, and are more secure than the equivalents from the C standard library. Users are responsible for allocating enough storage required for std::to_chars , or the function will fail by setting the error code object in its return value. These functions allow you to optionally pass a base (defaults to base-10) or a format specifier for floating type input. © std::to_chars returns a (non-const) char pointer which is one-past-the-end of the string that, the function wrote to inside the given buffer, and an error code object. © std::from_chars returns a const char pointer which on success is equal to the end pointer passed to the function, and an error code object. Both error code objects returned from these functions are equal to the default-initialized error code object on success. Convert the number 123 toa std::string : ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave sai62 2024. 03.08.1700 ‘AnthonyCalandramoderm-op-features:Achealshee of modem C++ language and ibrar features const int n = 123; e // Can use any container, string, array, etc. std::string str; str.resize(3); // hold enough storage for each digit of “n* const auto [ ptr, ec ] = std::to_chars(str.data(), str.data() + str.size(), n); if (ec == std:rerre{}) { std::cout << str << std::endl; } // 123 else { /* handle failure */ } Convert from a std::string with value "123" to an integer: const std::string ste{ 123" }5 e int 93 const auto [ ptr, ec ] = std::from_chars(str.data(), str.data() + str.size(), n)5 if (ec == std:serre{}) { std::cout << n << std:zendl; } // 123 else { /* handle failure */ } C++14 Language Features Binary literals Binary literals provide a convenient way to represent a base-2 number. It is po digits with * . le to separate eb110 // == 6 e eb11i1'it11 // == 255 Generic lambda expressions C+#14 now allows the auto type-specifier in the parameter list, enabling polymorphic lambdas. auto identity = [](auto x) { return x; }5 a int three = identity(3); // std::string foo = identity("fo Foo! Lambda capture initializers This allows creating lambda captures initialized with arbitrary expressions. The name given to the captured value does not need to be related to any variables in the enclosing scopes and introduces ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 462 2024.09.08. 17.00 Anthony Calandrafmodernppfealures:Achealsheot of modern C++ language and ibrary feature. a new name inside the lambda body. The initializing expression is evaluated when the lambda is created (not when it is invoked). int factory(int i) { return i * 10; } oa auto f = [x = factory(2)] { return x; }; // returns 20 auto generator = [x = @] () mutable { // this would not compile without ‘mutable’ as we are modifying x on each call return x++5 ub auto a = generator(); // auto b = generator(); // auto c = generator(); // Because it is now possible to move (or forward) values into a lambda that could previously be only captured by copy or reference we can now capture move-only types in a lambda by value. Note that in the below example the p in the capture-list of task2 on the left-hand-side of = is anew variable private to the lambda body and does not refer to the original p auto p = std::make_uniquecint>(1)5 o auto taski = [=] { *p = 5; I vs. auto task2 = [p = std::move(p)] { *p = 5; }3 // OK: p is move-constructed into the clo // the original p is empty after task2 is created 5 // ERROR: std: :unique_ptr cannot be copied Using this reference-captures can have different names than the referenced variable. auto x = 43 a auto f = [&r =x, x= x * 10] { return r+ x; b #()3 // sets x to 2 and returns 12 Return type deduction Using an auto return type in C++14, the compiler will attempt to deduce the type for you. With lambdas, you can now deduce its return type using auto , which makes returning a deduced reference or rvalue reference possible. // deduce return type as “int”. @ auto f(int 4) { return i; 3 ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 6162 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, template oe auto& #(T& t) { return t; // Returns a reference to a deduced type. auto g = [](auto& x) -> auto& { return f(x); }5 int y = 123; int& z= g(y)3 // reference to “y decltype(auto) The decitype(auto) type-specifier also deduces a type like auto does. However, it deduces return types while keeping their references and cv-qualifiers, while auto will not. const int x = @5 e auto x1 = x; // int decltype(auto) x2 int y = 93 int&@ yl = y5 auto y2 = yl; // int decltype(auto) y3 = y1; // inte int@a z = 0; auto 21 = st // const int move(z)3 // int decltype(auto) 22 = std::move(z); // intee // Note: Especially useful for generic code! oe // Return type is “int™. auto #(const int& i) { return i; } // Return type is “const inta’. decltype(auto) g(const int& i) { return i; } int x = 123; static_assert(std static_assert(std static_assert(std sis_samecconst int&, decltype((x))>::value 's_same::value 'S_same:: See also: decltype (C++11) . Relaxing constraints on constexpr functions ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 6162 2024. 03.08.1700 ‘AnthonyCalandramoderm-op-features:Achealshee of modem C++ language and ibrar features In C+#11, constexpr function bodies could only contain a very limited set of syntaxes, including (but not limited to): typedef s, using s, anda single return statement. In C++14, the set of allowable syntaxes expands greatly to include the most common syntax such as if statements, multiple return s, loops, etc constexpr int factorial(int n) { oa if (nce 4) ¢ return 13 } else { return n * factorial(n - 1); > t factorial(5); // == 126 Variable templates C++14 allows variables to be templated: template e constexpr T pi = 1(3.1415926535897932385) ; template constexpr Te = T(2.7182818284590452353) ; [[deprecated]] attribute C++14 introduces the [[deprecated]] attribute to indicate that a unit (function, class, etc) is discouraged and likely yield compilation warnings. If a reason is provided, it will be included in the warnings. [[deprecated]] @ void old_method(); [[deprecated("Use new_method instead")]] void legacy_method(); C++14 Library Features User-defined literals for standard library types New user-defined literals for standard library types, including new built-in literals for chrono and basic_string . These can be constexpr meaning they can be used at compile- time. Some uses for these literals include compile-time integer parsing, binary literals, and imaginary number literals, ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave anie2 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, using namespace std::chrono_literals; oe auto day = 24h day.count(); // == 24 std: schrono: :duration_cast(day).count(); // 1440 Compile-time integer sequences The class template std: :integer_sequence represents a compile-time sequence of integers. There are a few helpers built on top: std: :make_integer_sequencecT, N> - creates a sequence of @, ..., N - 1 with type T # std: :index_sequence_for a decltype(auto) a2t_impl(const Array& a, st jake_tuple(a[I]...)3 integer_sequence& a) { return a2t_impl(a, Indices()); 3 make_index_sequence> std::make_unique std::make_unique is the recommended way to create instances of std: :unique_ptr s due to the following reasons: * Avoid having to use the new operator. * Prevents code repetition when specifying the underlying type the pointer shall hold * Most importantly, it provides exception-safety. Suppose we were calling a function foo like so: foo(std tunique_ptr{new T{}}, function_that_throws(), std::unique_pte{new 1(}}); @ The compiler is free to call new T(}, then function_that_throws() , and so on... Since we have allocated data on the heap in the first construction of aT , we have introduced a leak here. With std::make_unique , we are given exception-safety: foo(std::make_unique(), function_that_throws(), std: :make_unique()); oa ntpsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave sai62 2024, 08.05. 17:00 ‘AnthonyCalandralmoder-cpp-features: A chealsheet of modecn C++ language and library features, See the section on smart pointers (C++11) for more information on std::unique_ptr and std::shared_ptr . C++11 Language Features Move semantics Moving an object means to transfer ownership of some resource it manages to another object. The first benefit of move semantics is performance optimization. When an object is about to reach the end of its lifetime, either because it's a temporary or by explicitly calling std::move , a move is often a cheaper way to transfer resources. For example, moving a. std::vector is just copying some pointers and internal state over to the new vector -- copying would involve having to copy every single contained element in the vector, which is expensive and unnecessary if the old vector will soon be destroyed Moves also make it possible for non-copyable types such as std: :unique_ptr s (smart pointers) to guarantee at the language level that there is only ever one instance of a resource being managed ata time, while being able to transfer an instance between scopes. See the sections on: rvalue references, special member functions for move semantics, std::move, std::forward, forwarding references . Rvalue references C+#11 introduces a new reference termed the rvalue reference. An rvalue reference tot , which is a non-template type parameter (such as int , or a user-defined type), is created with the syntax Ta& . Rvalue references only bind to rvalues. Type deduction with Ivalues and rvalues: int x = 0; // “x” is an lvalue of type “int a int& x1 = x; // “x1” is an Ivalue of type “int& int@& xr = x5 // compiler error is an Ivalue int@& xr2 = 5 // “xr2° is an lvalue of type “int&& -- binds to the rvalue tenporary, void f(int& x) {} void (int@a x) (} (x5 // calls f(inta) (x1); // calls #(int&) (3); // calls f(int@a) F(stdz:move(x))3 // calls f(int@&) #(xr2)5 // calls #(inta) F(stdi:move(xr2)); // calls f(int@& x) See also: std::move , std::forward, forwarding references . ntipsilgthub.com/AnthonyCalandalmadem-cpp-featuresistdmave 0162

You might also like