Skip to content

Latest commit

 

History

History
363 lines (265 loc) · 8.45 KB

README.md

File metadata and controls

363 lines (265 loc) · 8.45 KB

C++20 Overview

license cpp20

📌 Please note that

  1. The idea of this overview is self education
  2. The main goal - keep it simple and short
  3. And it is primarily based on CppCon 2019 and Meeting C++ 2019 talks

⚠️ There is no guarantee that below theoretical and practical parts are correkt and up to date

Contents

  1. Modules
  2. Ranges
  3. Coroutines
  4. Concepts
  5. Concurrency
  6. Calendars and Timezones
  7. Initialization
  8. Lambda Expression
  9. Attributes
  10. Constant Expressions
  11. Bit Operations
  12. Source Location
  13. Spaceship Operator

[Unstructured] Contents

  1. Abbreviated Function Templates
  2. Non-Type Template Parameters
  3. span
  4. Feature-Test Macros
  5. <version>
  6. Class Enums and using
  7. Text Formatting
  8. char8_t
  9. Math Constants
  10. Small Standard Library Additions
  11. bind_front
  12. Strucutre Binding

Abbreviated Function Templates

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 that auto was allowed before

⬆️ Back to Contents

Non-Type Template Parameters

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">();
}

⬆️ Back to Contents

span

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);

⬆️ Back to Contents

Feature-Test Macros

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

⬆️ Back to Contents

<version>

Supplies implementation-dependent information about the standard library:

  • Version number
  • Release date
  • Copyright notice
  • Additional implementation-defined information
  • Include the library feature-test macros

⬆️ Back to Contents

Class Enums and using

🔎 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";
  }
}

⬆️ Back to Contents

Text Formatting

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!

⬆️ Back to Contents

char8_t

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 and signed 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, 🌎!");

⬆️ Back to Contents

Math Constants

Following mathematical constant are defined:

  • e, log2e, log10e
  • pi, inv_pi, inv_sqrtpi
  • ln2, ln10
  • sqrt2, sqrt3, inv_sqrt3
  • egamma
  • phi

🔗 Additional Links

⬆️ Back to Contents

Small Standard Library Additions

  • starts_with and ends_with for basic_string/basic_string_view
  • contains for associative containers
  • remove, remove_if, and unique methods for list and forward_list now return size_type (number of removed elements) insted of void
  • erase and erase_if algorithms equivalent to c.erase(std::remove_if(c.begin(), c.end(), pred), c.end()); now
  • shift_left and shift_right added to <algorithm>
  • midpoint to calculates the midpoint of two numbers

⬆️ Back to Contents

bind_front

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

⬆️ Back to Contents

Strucutre Binding

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
}

⬆️ Back to Contents