Π£Ρ‚Π²Π΅Ρ€ΠΆΠ΄Ρ‘Π½ стандарт C++20

ΠšΠΎΠΌΠΈΡ‚Π΅Ρ‚ ISO ΠΏΠΎ стандартизации языка C++ ΡƒΡ‚Π²Π΅Ρ€Π΄ΠΈΠ» ΠΌΠ΅ΠΆΠ΄ΡƒΠ½Π°Ρ€ΠΎΠ΄Π½Ρ‹ΠΉ стандарт «C++20«. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½Π½Ρ‹Π΅ Π² спСцификации возмоТности, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹Ρ… случаСв, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π² компиляторах GCC, Clang ΠΈ Microsoft Visual C++. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠ΅ C++20 стандартныС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Boost.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π΄Π²Π° мСсяца утвСрТдённая спСцификация Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π½Π° стадии ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠΈ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° ΠΊ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° ΠΏΠΎ рСдакторской ΠΏΡ€Π°Π²ΠΊΠ΅ орфографичСских ошибок ΠΈ ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΎΠΊ. Π’ Π½Π°Ρ‡Π°Π»Π΅ ноября Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ Π² ISO для ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ΄ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ ISO/IEC 14882:2020. Π’Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ, ΠΊΠΎΠΌΠΈΡ‚Π΅Ρ‚ ΡƒΠΆΠ΅ приступил ΠΊ Ρ€Π°Π±ΠΎΡ‚Π΅ Π½Π°Π΄ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ стандартом C++23 (C++2b) ΠΈ Π½Π° блиТайшСм Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΌ совСщании рассмотрит Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Π½ΠΎΠ²ΡˆΠ΅ΡΡ‚Π²Π°.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ особСнности C++20 (ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΠ΄Π°):

  • Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ «ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ», Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ шаблонов, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π½Π°Π±ΠΎΡ€ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌ шаблона, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎ врСмя компиляции ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°ΡŽΡ‚ Π½Π°Π±ΠΎΡ€ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒΡΡ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² шаблона. ΠšΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ логичСских нСсоотвСтствий ΠΌΠ΅ΠΆΠ΄Ρƒ свойствами Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π²Π½ΡƒΡ‚Ρ€ΠΈ шаблона, ΠΈ свойствами Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².

    template<typename T>
    concept EqualityComparable = requires(T a, T b) {
    { a == b } -> std::boolean;
    { a != b } -> std::boolean;
    };

  • Π’ состав приняты Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с модулями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ вмСсто Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ². ΠœΠΎΠ΄ΡƒΠ»ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π½ΠΎΠ²Ρ‹ΠΉ способ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ исходных тСкстов Π½Π° основании опрСдСлСния Π³Ρ€Π°Π½ΠΈΡ† ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Π±Π΅Π· ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌΡ‹Ρ… Ρ‡Π΅Ρ€Π΅Π· «#include» Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ².
  • ΠœΠ°ΠΊΡ€ΠΎΡ __VA_OPT__ для Π°Π΄Π°ΠΏΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ раскрытия Π²Π°Ρ€ΠΈΠ°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… макросов Π² зависимости ΠΎΡ‚ наличия Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Π² Π²Π°Ρ€ΠΈΠ°Ρ‚ΠΈΠ²Π½ΠΎΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π΅.
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° «» для трСхстороннСго сравнСния.
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ² элСмСнтов ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для Π±ΠΈΡ‚ΠΎΠ²Ρ‹Ρ… ΠΏΠΎΠ»Π΅ΠΉ.
  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ лямбда-Π·Π°Ρ…Π²Π°Ρ‚Π° Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ «*this».

    struct int_value {
    int n = 0;
    auto getter_fn() {
    // BAD:
    // return [=]() { return n; };

    // GOOD:
    return [=, *this]() { return n; };
    }
    };

  • Π’Ρ‹Π·ΠΎΠ² элСмСнтов ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ (Pointer-to-member), ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Π΅ Ρ‡Π΅Ρ€Π΅Π· Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ «const &» ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹.
  • ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ delete с дСструктором, описанный Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π΅ P0722R1.
  • Классам Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΎ использованиС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ шаблона Π±Π΅Π· Ρ‚ΠΈΠΏΠ°.

    struct foo {
    foo() = default;
    constexpr foo(int) {}
    };

    template <foo f>
    auto get_foo() {
    return f;
    }

    get_foo(); // uses implicit constructor
    get_foo<foo{123}>();

  • НС сохраняСмыС лямбда-выраТСния с конструктором.
  • Π”ΠΎΠΏΡƒΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ использования синтаксиса шаблонов для Π»Π°ΠΌΠ±Π΄Π°-Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ («auto f = []<typename T>(std::vector<T> v)»).
  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ использования строковых Π»ΠΈΡ‚Π΅Ρ€Π°Π»ΠΎΠ² Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°Ρ… шаблона.
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° синтаксиса ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π² стилС Π‘ΠΈ — явно Π½Π΅ пСрСчислСнныС Π² спискС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ поля, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

    struct A {
    int x;
    int y;
    int z = 123;
    };

    A a {.x = 1, .z = 2}; // a.x == 1, a.y == 0, a.z == 2

  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° пустых Ρ‡Π»Π΅Π½ΠΎΠ² структур Π΄Π°Π½Π½Ρ‹Ρ….
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² likely ΠΈ unlikely для информирования ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ‚ΠΎΡ€Π° ΠΎ вСроятности срабатывания условной конструкции («[[likely]] if (random > 0) {«).
  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ использования Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ΠΎΠ² для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π² Ρ†ΠΈΠΊΠ»Π΅ «for»

    for (auto v = std::vector{1, 2, 3}; auto& e : v) {

  • АвтоматичСскоС вычислСниС Ρ€Π°Π·ΠΌΠ΅Ρ€Π° массива Π² new («new double[]{1,2,3}»);
  • Атрибут «[[no_unique_address]]» ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π±Π΅Π· Π΄Π°Π½Π½Ρ‹Ρ… Π½Π΅ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ мСста.
  • АтомарныС ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ (std::atomic<shared_ptr<T>> ΠΈ std::atomic<weak_ptr<T>>).
  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π² условных выраТСниях.
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° быстрых (immediate) Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с константами.

    consteval int sqr(int n) {
    return n * n;
    }

    constexpr int r = sqr(100); // OK
    int x = 100;
    int r2 = sqr(x); // ERROR: ‘x’ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ константа

  • Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ примСнСния constexpr с Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями («constexpr virtual int f() const { return 2; }»).
  • Π’ стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅:
    • Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ‚ΠΈΠΏΠ° char8_t для строк UTF-8.
    • Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ bit (Π±ΠΈΡ‚ΠΎΠ²Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ) ΠΈ version.
    • Появилась Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ прСфикса ΠΈ суффикса строк (starts_with, ends_with).
    • Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Ρ‚ΠΈΠΏΠ°ΠΆΠΈ std::remove_cvref, std::unwrap_reference, std::unwrap_decay_ref, std::is_nothrow_convertible ΠΈ std::type_identity.
    • Π”ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ std::midpoint, std::lerp, std::bind_front, std::source_location, std::visit, std::is_constant_evaluated ΠΈ std::assume_aligned.
    • Π’ std::make_shared Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° массивов.
    • Π”ΠΎΠ±Π°Π²Π»Π΅Π½Π° функция std::to_array для прСобразования ΠΏΠΎΡ…ΠΎΠΆΠΈΡ… Π½Π° массив ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² std::array.
  • Π‘ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ синтаксис пСрСчислСний:

    enum class rgba_color_channel { red, green, blue, alpha };

    std::string_view to_string(rgba_color_channel my_channel) {
    switch (my_channel) {
    using enum rgba_color_channel;
    case red: return «red»;
    case green: return «green»;
    case blue: return «blue»;
    case alpha: return «alpha»;
    }
    }

  • Π’ индСксах ΠΈΠ·-Π·Π° Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ³ΠΎ повСдСния Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΎ использованиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ «,» («a[b,c]»). ΠŸΡ€Π΅ΠΊΡ€Π°Ρ‰Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ, ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΌΠΈ с ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ словом volatile, Π² Ρ‚ΠΎΠΌ числС Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½Ρ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ «++» ΠΈ «—» со стандартными Ρ‚ΠΈΠΏΠ°ΠΌΠΈ.
  • Π‘ΠΎΠΊΡ€Π°Ρ‰Π΅Π½ΠΎ число ситуаций, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… трСбуСтся ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ «typename» для ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΎ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Ρ‚ΠΈΠΏΠ°.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: opennet.ru