C++20

C++20 — версія стандарту ISO/IEC 14882 мови програмування C++. Слідує після C++17.[1] Комітет стандарту C++ почав працювати над C++20 в липні 2017.[2] З технічного боку стандарт було завершено[3] комітетом WG21 до зустрічі в Празі в лютому 2020,[4] остаточно затверджено 4 вересня 2020 року. Стандарт офіційно опублікований у грудні 2020.[5]

C++20 додає більше нових можливостей ніж C++14 чи C++17.

Нові можливості мови

Співпрограми

До версії C++20 можливість роботи зі співпрограмами була реалізована на рівні бібліотек, зокрема Boost.Coroutine, Boost.Coroutine2 та іншими. У версії C++20 на рівні мови та компілятора була додана підтримка безстекових співпрограм. Зокрема, були додані нові ключові слова co_return, co_await та co_yield, але підтримка співпрограм у стандартній бібліотеці була мінімальна[10], стандарт радше визначив каркас для роботи зі співпрограмами[11]. Тому, для зручності розробників, були створені бібліотеки класів для поширених видів співпрограм: cppcoro, libcoro, QCoro, та інші[10].

Стандартом передбачено, що співпрограма може віддати управління в одному потоці виконання, а бути відновлена — в іншому[12].

В стандарті C++23 до стандартної бібліотеки був доданий тип generator, який полегшує створення генераторів послідовностей на основі співпрограм сумісних з доданими в стандарті C++20 діапазонами[13].

Таким чином, генератор послідовності Фібоначчі мовою стандарту C++23 може мати такий вигляд:

#include <generator>
#include <ranges>
#include <iostream>
 
std::generator<int> fib() {
    co_yield 0;
    auto a = 0;
    auto b = 1;
    for (auto n : std::views::iota(0)) {  
        auto next = a + b;
        a = b;
        b = next;
        co_yield next;
    }
}

int main() {
    for (auto f : fib() | std::views::take(10)) {
        std::cout << f << " ";
    }
}

Нові можливості бібліотеки

  • Діапазони (англ. ranges)[14]
  • Атомарні розумні вказівники (std::atomic<std::shared_ptr<T>> та std::atomic<std::weak_ptr<T>>)[15][16]

Нові (і змінені) ключові слова

  • новий оператор «зореліт» для тришляхового порівняння: operator <=>
  • concept
  • char8_t
  • тепер explicit може приймати вираз значення якого визначає чи буде явною функція до якої застосовано explicit.[17]
  • constinit[18]
  • consteval

Пов'язані зі співпрограмами

  • co_await
  • co_return
  • co_yield

Пов'язані з модулями

  • import (як ідентифікатори з особливим значенням)
  • module (як ідентифікатори з особливим значенням)
  • requires
  • export (нове значення)

Нові атрибути[19]

  • [[likely]]
  • [[unlikely]]
  • [[no_unique_address]]

Видалені та заборонені можливості

Видалені можливості:[20]

  • Заголовкові файли породжені від заголовкових файлів C <ccomplex>, <ciso646>, <cstdalign>, <cstdbool> і <ctgmath>, так як немає сенсу їх використовувати в C++. Відповідні <*.h> все ще підтримуються для сумістності з C.
  • Використання throw() для позначення динамічної специфікації виключень функцій.
  • Деякі можливості бібліотеки які раніше були заборонені тепер видалені: std::uncaught_exception, std::raw_storage_iterator, std::is_literal_type, std::is_literal_type_v, std::result_of і std::result_of_t.

Заборонені можливості:

  • використання оператора коми в виразах для індексів[21]
  • (більшість з) volatile[22]

Можливості опубліковані як технічні специфікації

  • Паралелізм ТС v2[23] (включаючи блоки задач[24])
  • Рефлексія ТС v1[25]
  • Мережеві розширення ТС v1[26]

Зміни відкладені до наступних стандартів

  • Контракти — утворено нову робочу групу (SG21) для роботи над новою пропозицією[27]
  • Рефлексія[28][29]
  • Метакласи[30]
  • Виконавці[31]
  • Мережеві розширення,[32][33] включаючи async, базові I/O служби, таймери, буфери і буферо-орієнтовані потоки, сокети і Інтернет протоколи (заблоковані виконавцями)
  • Властивості[34]
  • Розширення для future[35]

Історія розвитку стандарту

липень 2017

Наступне було проголосовано для включення в чорновик стандарту C++20 в липні 2017:[36]

struct A { int x; int y; int z; };
A a{.y = 2, .x = 1}; // помилка; порядок ініціалізаторів не відповідає порядку в означені
A b{.x = 1, .z = 2}; // добре, b.y ініціалізоване в 0
  • [=, this] захоплення лямбди[38]
  • Шаблонний список параметрів лямбди[39]
  • std::make_shared і std::allocate_shared для масивів[40]

листопад 2017 (Альбукерке)

for (T thing = foo(); auto& x : thing.items()) { /* ... */ } // Добре
  • лямбди в необчислюваних контекстах (наприклад, в decltype)[42][43]
  • конструйовні за замовчанням і з можливістю присвоювання лямбди без стану.[42][44] Це робить лямбди без стану більше схожими на функціональні об'єкти
  • дозволити розкриття паку в ініціалізаційному захоплені лямбди[42][45], як-от [args=std::move(args)...]() -> ...
  • рядкові літерали як параметри не типи шаблонів[42][46]
  • атомарні вказівники (такі як std::atomic<shared_ptr<T>> і std::atomic<weak_ptr<T>>)[47]
  • std::to_address переводить вказівник, в тому числі розумний, в сирий вказівник[48]

березень 2018 (Джексонвіль)

  • в деяких ситуаціях прибирає потребу в typename[49]
  • нові стандартні атрибути [[no_unique_address]],[50] [[likely]] і [[unlikely]][51]
  • доповнення до календаря і часових поясів у <chrono>[52]
  • std::span, надає вид на масив (аналогічний до std::string_view, але span не тільки для читання).[53] Зазвичай втілюється за допомогою вказівника на початок і розміру.
  • заголовковий файл <version> [54]

червень 2018 (Раперсвіль)

Зміни, що їх було внесено в робочу чернетку C++20 під час літньої зустрічі в червні 2018 в Раперсвілі включають:[55]

  • контракти було відкладено до пізніших стандартів[56]
  • макроси тестування наявності функціональності[57]. Наприклад, __cpp_lib_coroutine, __cpp_concepts
  • побітове перетворення представлень об'єктів менш багатослівне ніж memcpy() і придатніше для використання внутрішніх можливостей компілятора[58]. Див. std::bit_cast
  • умовний explicit, що дозволяє модифікатору залежати від логічного виразу[59]
template<class T> struct wrapper { 
  template<class U> explicit(!std::is_convertible_v<U, T>) wrapper(U const& u) : t_(u) {} 
  T t_; 
};
  • constexpr віртуальні функції[60]

листопад 2018 (Сан-Дієго)

лютий 2019 (Кона)

  • Coroutines[61]
  • Модулі.[62] Уже підтримуються Clang 5[63] та Visual Studio 2015 Update 1

липень 2019 (Кельн)

Зміни внесені до робочої чернетки C++20 під час літньої зустрічі в липні 2019 [Архівовано 24 листопада 2019 у Wayback Machine.] (Кельн) включають:[64][65][66]

    a[b,c];   // небажано
    a[(b,c)]; // прийнятно
  • (більшість з) volatile було позначено небажаними[22]
  • доповнення для constexpr (трівіальна ініціалізація за замовчанням,[68] дозволяє вбудований асемблер у випадках, коли він не обчилюється під час компіляції[69])

листопад 2019 (Белфаст)

Примітки

  1. ↑ The next standard after C++17 will be C++20. Архів оригіналу за 8 жовтня 2016. Процитовано 29 вересня 2017., by Herb Sutter
  2. ↑ Current Status : Standard C++. Архів оригіналу за 8 вересня 2020. Процитовано 29 вересня 2017.
  3. ↑ Sutter, Herb (1 жовтня 2019). P1000R3: C++ IS schedule (PDF). Архів оригіналу (PDF) за 14 листопада 2019. Процитовано 13 лютого 2020.
  4. ↑ Dusíková, Hana (6 листопада 2019). N4817: 2020 Prague Meeting Invitation and Information (PDF). Архів (PDF) оригіналу за 29 грудня 2019. Процитовано 13 лютого 2020.
  5. ↑ ISO/IEC 14882:2020. Архів оригіналу за 16 грудня 2020. Процитовано 5 листопада 2021.
  6. ↑ а б P0606R0: Concepts Are Ready (PDF). Архів оригіналу (PDF) за 28 березня 2017. Процитовано 29 вересня 2017.
  7. ↑ P1141R1 - Yet another approach for constrained declarations. Архів оригіналу за 11 листопада 2018. Процитовано 5 листопада 2021.
  8. ↑ N4720: Working Draft, Extensions to C++ for Modules (PDF). Архів оригіналу (PDF) за 30 квітня 2019. Процитовано 5 листопада 2021.
  9. ↑ N4649: Working Draft, Technical Specification on C++ Extensions for Coroutines (PDF). Архів оригіналу (PDF) за 16 травня 2017. Процитовано 29 вересня 2017.
  10. ↑ а б Valentyn Korniienko (25 квітня 2023). С++20 Coroutines та огляд бібліотек, які реалізують підтримку со-програм. DOU.
  11. ↑ Rainer Grimm (23 жовтня 2019). C++20: The Big Four.
  12. ↑ Coroutines (C++20). CPP Reference. 27 жовтня 2023. Процитовано 4 листопада 2023.
  13. ↑ Rainer Grimm (18 вересня 2023). C++23: Ranges Improvements and std::generator.
  14. ↑ The One Ranges Proposal (PDF). Архів оригіналу (PDF) за 11 листопада 2018. Процитовано 5 листопада 2021.
  15. ↑ Meredith, Alisdair; Sutter, Herb. Revising atomic_shared_ptr for C++20. Архів оригіналу за 4 січня 2018. Процитовано 13 березня 2020.
  16. ↑ P1664R0: Add wait/notify to atomic<shared_ptr<T>>. Архів оригіналу за 5 листопада 2021. Процитовано 5 листопада 2021.
  17. ↑ explicit specifier - cppreference.com. en.cppreference.com. Архів оригіналу за 21 лютого 2012. Процитовано 4 серпня 2019.
  18. ↑ P1143R2: Adding the constinit keyword. www.open-std.org. 20 липня 2019. Архів оригіналу за 20 серпня 2019. Процитовано 20 липня 2019.
  19. ↑ attribute specifier sequence(since C++11) - cppreference.com. en.cppreference.com. Архів оригіналу за 5 липня 2012. Процитовано 4 серпня 2019.
  20. ↑ Working Draft, Standard for Programming Language C++ (Annex C, §C.1) (PDF). Архів оригіналу (PDF) за 27 квітня 2020. Процитовано 4 листопада 2021.
  21. ↑ а б P1161R2: Deprecate uses of the comma operator in subscripting expressions. www.open-std.org. Архів оригіналу за 20 липня 2019. Процитовано 20 липня 2019.
  22. ↑ а б P1152R4: Deprecating volatile. www.open-std.org. 20 липня 2019. Архів оригіналу за 23 червня 2019. Процитовано 20 липня 2019.
  23. ↑ C++ Extensions for Parallelism Version 2.
  24. ↑ Task Blocks. Архів оригіналу за 19 вересня 2017. Процитовано 29 вересня 2017.
  25. ↑ C++ Extensions for Reflection.
  26. ↑ C++ Extensions for Networking.
  27. ↑ Sutter, Herb (20 липня 2019). Trip report: Summer ISO C++ standards meeting (Cologne). Sutter’s Mill (англ.). Архів оригіналу за 17 квітня 2020. Процитовано 21 липня 2019.
  28. ↑ Reflections on the reflection proposals - Meeting C++. meetingcpp.com (англ.). Архів оригіналу за 23 червня 2017. Процитовано 30 червня 2017.
  29. ↑ Static reflection. www.open-std.org. Архів оригіналу за 22 лютого 2020. Процитовано 10 листопада 2018.
  30. ↑ Herb Sutter. Metaclasses (PDF). Архів оригіналу (PDF) за 11 листопада 2020. Процитовано 29 вересня 2017.
  31. ↑ A Unified Executors Proposal for C++. www.open-std.org. Архів оригіналу за 20 лютого 2020. Процитовано 24 лютого 2019.
  32. ↑ N4771: Working Draft, C++ Extensions for Networking (PDF). Архів оригіналу (PDF) за 19 квітня 2020. Процитовано 8 березня 2020.
  33. ↑ ISO/IEC TS 19216:2018 Programming Languages -- C++ Extensions for Networking. Архів оригіналу за 15 січня 2019. Процитовано 8 березня 2020.
  34. ↑ A General Property Customization Mechanism. www.open-std.org. Архів оригіналу за 19 січня 2020. Процитовано 24 лютого 2019.
  35. ↑ A Unified Futures Proposal for C++.
  36. ↑ Herb Sutter. Trip report: Summer ISO C++ standards meeting (Toronto). Архів оригіналу за 6 серпня 2017. Процитовано 29 вересня 2017.
  37. ↑ Tim Shen; Richard Smith. Designated Initialization Wording. Архів оригіналу за 15 жовтня 2017. Процитовано 29 вересня 2017.
  38. ↑ Thomas Köppe. Allow lambda capture [=, this]. Архів оригіналу за 9 лютого 2019. Процитовано 29 вересня 2017.
  39. ↑ Familiar template syntax for generic lambdas. Архів оригіналу за 21 листопада 2018. Процитовано 29 вересня 2017.
  40. ↑ Extending make_shared to Support Arrays. Архів оригіналу за 6 вересня 2017. Процитовано 8 березня 2020.
  41. ↑ Range-based for statements with initializer. Архів оригіналу за 6 квітня 2017. Процитовано 11 березня 2020.
  42. ↑ а б в г Trip Report: C++ Standards Meeting in Albuquerque, November 2017. There's Waldo! (амер.). 20 листопада 2017. Архів оригіналу за 11 грудня 2017. Процитовано 11 грудня 2017.
  43. ↑ Wording for lambdas in unevaluated contexts (PDF). Архів оригіналу (PDF) за 12 грудня 2017. Процитовано 13 березня 2020.
  44. ↑ Default constructible and assignable stateless lambdas (PDF). Архів оригіналу (PDF) за 12 грудня 2017. Процитовано 13 березня 2020.
  45. ↑ Pack expansion in lambda init-capture. www.open-std.org. Архів оригіналу за 14 лютого 2020. Процитовано 11 грудня 2017.
  46. ↑ String literals as non-type template parameters (PDF). Архів оригіналу (PDF) за 11 грудня 2017. Процитовано 13 березня 2020.
  47. ↑ Meredith, Alisdair; Sutter, Herb. Revising atomic_shared_ptr for C++20. JTC1/SC22/WG21 - The C++ Standards Committee - ISOCPP. ISO. Архів оригіналу за 4 січня 2018. Процитовано 27 грудня 2018.
  48. ↑ Utility to convert a pointer to a raw pointer. Архів оригіналу за 20 лютого 2018. Процитовано 13 березня 2020.
  49. ↑ Nina Ranns; Daveed Vandevoorde. Down with typename!. Архів оригіналу за 22 квітня 2018. Процитовано 13 березня 2020.
  50. ↑ Language support for empty objects. Архів оригіналу за 17 квітня 2018. Процитовано 13 березня 2020.
  51. ↑ Proposed wording for likely and unlikely attributes (Revision 5). Архів оригіналу за 13 травня 2018. Процитовано 13 березня 2020.
  52. ↑ Howard E. Hinnant; Tomasz Kamiński. Extending <chrono> to Calendars and Time Zones. Архів оригіналу за 13 травня 2018. Процитовано 4 квітня 2020.
  53. ↑ Neil MacIntosh; Stephan T. Lavavej. span: bounds-safe views for sequences of objects. Архів оригіналу за 18 травня 2019. Процитовано 4 квітня 2020.
  54. ↑ Alan Talbot. <version>. Архів оригіналу за 18 травня 2019. Процитовано 4 квітня 2020.
  55. ↑ Герб Сатер. Trip report: Summer ISO C++ standards meeting (Rapperswil). Архів оригіналу за 23 травня 2020. Процитовано 4 квітня 2020.
  56. ↑ Support for contract based programming in C++. www.open-std.org. Архів оригіналу за 15 січня 2020. Процитовано 10 листопада 2018.
  57. ↑ Integrating feature-test macros into the C++ WD. www.open-std.org. Архів оригіналу за 20 липня 2018. Процитовано 10 листопада 2018.
  58. ↑ Bit-casting object representations. www.open-std.org. Архів оригіналу за 18 серпня 2018. Процитовано 10 листопада 2018.
  59. ↑ explicit(bool). www.open-std.org. Архів оригіналу за 20 липня 2018. Процитовано 13 листопада 2018.
  60. ↑ Allowing Virtual Function Calls in Constant Expressions. www.open-std.org. Архів оригіналу за 11 червня 2018. Процитовано 11 березня 2019.
  61. ↑ N4649: Working Draft, Technical Specification on C++ Extensions for Coroutines (PDF). Архів оригіналу (PDF) за 16 травня 2017. Процитовано 29 вересня 2017.
  62. ↑ N4637: Working Draft, Extensions to C++ for Modules (PDF). Архів оригіналу (PDF) за 5 липня 2017. Процитовано 29 вересня 2017.
  63. ↑ Clang 5 documentation on Modules. Архів оригіналу за 7 жовтня 2017. Процитовано 29 вересня 2017.
  64. ↑ r/cpp - 2019-07 Cologne ISO C++ Committee Trip Report — 🚀 The C++20 Eagle has Landed 🚀 (C++20 Committee Draft shipped; Contracts Moved From C++20 to a Study Group; `std::format` in C++20; C++20 Synchronization Library). reddit (англ.). Архів оригіналу за 20 квітня 2020. Процитовано 15 вересня 2019.
  65. ↑ Botond Ballo. Trip Report: C++ Standards Meeting in Cologne, July 2019. Архів оригіналу за 26 лютого 2020. Процитовано 8 березня 2020.
  66. ↑ Sutter, Herb. Trip report: Summer ISO C++ standards meeting (Cologne). Архів оригіналу за 17 квітня 2020. Процитовано 8 березня 2020.
  67. ↑ Josuttis, Nicolai. P1823R0: Remove Contracts from C++20 (PDF). Архів оригіналу (PDF) за 13 серпня 2020. Процитовано 8 березня 2020.
  68. ↑ Permitting trivial default initialization in constexpr contexts (PDF). Архів оригіналу (PDF) за 19 жовтня 2020. Процитовано 8 березня 2020.
  69. ↑ P1668R1: Enabling Constexpr Intrinsics By Permitting Unevaluated inline-asm in Constexpr Functions. www.open-std.org. Архів оригіналу за 19 січня 2020. Процитовано 20 липня 2019.

Посилання