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 Сoroutines та огляд бібліотек, які реалізують підтримку со-програм. 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.

Посилання[ред. | ред. код]