C++23

C++23 — наступна версія міжнародного стандарту ISO/IEC 14882 мови програмування C++, яка прийшла на заміну версії C++20. Остаточний проєкт стандарту отримав код N4950[1][2].

В лютому 2020 року на зустрічі у Празі був ухвалений загальний план нововведень для C++23, зокрема:[3][4] підтримка співпрограм у стандартній бібліотеці, модуляризація стандартної бібліотеки, впровадження механізмів виконання (англ. executors), та мережеві інтерфейси.

Перша зустріч робочої групи WG21 присвячена C++23 мала відбутись на початку червня 2020 року у Варні (Болгарія), але була скасована через пандемію коронавірусу[5][6]. Так само була скасована наступна зустріч в листопаді 2020 року в Нью-Йорку (Сполучені Штати)[7][6] та в лютому 2021 в Кона (на Гаваях)[7]. Натомість, всі зустрічі до листопада 2022 року відбувались віддалено через інтернет до фінальної зустрічі в лютому 2023 року.[7] Стандарт був технічно доопрацьований WG21 на гібридній зустрічі в Іссаква в лютому 2023 року.[8]

Сучасний приклад «Hello, world»

Програма Hello, world! тепер має такий вигляд з використанням засобів стандарту C++23:

import std;

int main()
{
    std::println("Hello, world!");
}

Оновлення у версії С++23

Зміни, які були прийняті в C++23, включають:

Мова

  • Параметр явного об'єкта [1] this
  • if consteval [2]
  • Багатовимірний підіндексний оператор [3]
  • Статичні оператори виклику та підрядкових індексів та статичні лямбда [4][5]
  • Спрощення неявного ходу [6]
  • auto(x) та auto{x} [7]
  • Нові директиви препроцесора:
    • #elifdef і [8] #elifndef
    • [9] #warning
  • Подовження часу життя деяких тимчасових установок у циклі for на основі діапазону [10]
  • Новий стандартний атрибут [[assume(expression)]] [11]
  • Вирахування аргументу шаблону класу з успадкованих конструкторів [12]
  • Мітки в кінці складеного оператора [13]
  • Оголошення псевдонімів в init-statements [14]
  • Літеральні суфікси for та відповідний знаковий тип std::size_t [15]
  • Розширені типи з плаваючою комою з літералами (умовно підтримуються) [16]
  • Необов'язковий з нульових лямбда-виразів ()
  • Атрибути в лямбда-виразах [17]
  • constexpr Зміни:
    • Нелітеральні змінні, мітки та s у функціях [18] gotoconstexpr
    • Допустимі та змінні, які використовуються в константних виразах у функціях [19] static,thread_localconstexpr
    • Функція типуconstexpr не потребує, щоб її тип повернення, і типи параметрів були літеральним типом
    • Тепер можна написати функцію, для якої жоден виклик не задовольняє вимогам основного виразу константи [20] constexpr
  • Звуження контекстуальних перетворень до in та [21] bool,static_assertif constexpr
  • Обрізання пробілів перед зрощуванням ліній [22]
  • Зроблено обов'язковим макет для порядку оголошення [23]
  • Відокремлені екрановані послідовності [24]
  • Визначені загальні витоки символів [25]
  • Зміни в кодуванні тексту:
    • підтримка UTF-8 як портативного кодування вихідного файлу [26]
    • Послідовне кодування символьних літер [27]
    • Набори символів та кодування [28]

Бібліотека

Підтримка модулів стандартної бібліотеки

  • стандартних модулів бібліотеки [29] std та std.compat

Підтримка бібліотеки Coroutine

  • Синхронна співпрограма для діапазонів [30] std::generator

Загальна підтримка утиліт

  • Тип результату [31] std::expected
  • Одинарні операції для [32] і [33] std::optionalstd::expected
  • Утиліта для отримання базового значення переліку [34] std::to_underlying
  • Обгортка, що викликається лише рухом [35] std::move_only_function
  • std::forward_like [36]
  • std::invoke_r [37]
  • std::bind_back [38]
  • std::byteswap [39]
  • std::unreachable: функція для позначення недоступного коду [40]
  • Зроблено сумісним з іншими кортежними об'єктами [41] std::tuple
  • std::basic_common_reference спеціалізація для отримання посилань для типів std::reference_wrapper [42]
  • Додавання аргументів за замовчуванням для конструктора пересиланняstd::pair [43]

Підтримка під час компіляції

  • constexpr Підтримка:
    • std::type_info::operator== [44]
    • std::bitset [45]
    • std::unique_ptr [46]
    • для деяких функцій<cmath> [47]
    • для інтегральних перевантажень і std::to_charsstd::from_chars [48]
  • Утиліти метапрограмування:
  • Типові знаки , [49], [50] , і [51] .std::is_scoped_enumstd::is_implicit_lifetimestd::reference_constructs_from_temporarystd::reference_converts_from_temporary
  • Додано підтримку типів лише з зсувом для операцій порівняння [52]

Ітератори, діапазони та підтримка алгоритмів

  • Нова функція перетворення діапазону std::ranges::to [53]
  • Новий алгоритм обмежених діапазонів:
    • std::ranges::starts_with
    • std::ranges::ends_with [54]
    • std::ranges::contains
    • std::ranges::contains_subrange [55]
    • std::ranges::find_last та інші варіанти [56]
    • Версії [57] iotashift_leftshift_right
    • Алгоритми згортання діапазону [58]
  • Новий, допоміжний засіб для визначення замикань адаптерів із визначеним діапазоном [59] std::ranges::range_adaptor_closure
  • Нові адаптери лінійки:
    • std::views::zip та інші варіанти
    • std::views::adjacent та інші варіанти [60]
    • std::views::join_with [61]
    • std::views::slide
    • std::views::chunk [62]
    • std::views::chunk_by [63]
    • std::views::as_rvalue [64]
    • std::views::as_const [65]
    • std::views::repeat [66]
    • std::views::stride [67]
    • std::views::cartesian_product [68]
    • std::views::enumerate [69]
  • Виправлення константних ітераторів, сентинелів та діапазонів, тобто та інших подібних утиліт, що повертають постійні ітератори, повинно бути повністю гарантовано навіть для неглибоких представлень (таких як )std::ranges::cbeginstd::span
  • Ітератори діапазонів як входи для алгоритмів, що не мають діапазонів [70]
  • Адаптери звільненого діапазону для використання лише типів зсуву [71]
  • Створення багатопараметричних конструкторів деяких представлень [72] explicit

Підтримка керування пам'яттю

  • std::out_ptr і для сумісності C [73] std::inout_ptr
  • std::allocate_at_least і [74] std::allocator::allocate_at_least
  • Явна функція управління життєвим часом для неявних типів [75] std::start_lifetime_as
  • Заборона спеціалізації користувача [76] std::allocator_traits

Підтримка обробки рядків і тексту

  • Нові функції-елементи та зміни в типах рядків:
    • std::basic_string_view::contains і [77] std::basic_string::contains
    • Відключення конструкції з for і [78] nullptrstd::basic_stringstd::basic_string_view
    • Конструктор явних діапазонів для [79] std::basic_string_view
    • std::basic_string::resize_and_overwrite [80]
    • Еталонне перевантаження Rvalue для ефективного нарізання [81] std::basic_string::substr
  • діапазони форматування, кортежі, екрановане представлення символів і рядків, а також трасування стека. [82] [83] [84] std::thread::id

Діагностична підтримка

  • Бібліотека Stacktrace [85]

Підтримка вводу/виводу

  • Форматованих функцій виводу і з нового заголовка [86] std::printstd::println<print>
  • spanstream library (-based string stream) з нового заголовка [87] std::span<spanstream>
  • Підтримка ексклюзивного режиму в S [88] std::fstream
  • std::basic_ostream::operator<<(const volatile void*) [89]

Підтримка контейнерів

  • Багатовимірний перехід [90][91][92][93] std::mdspan
  • Конструктивність і можливість призначення контейнерів з інших сумісних діапазонів [94]
  • Адаптери для контейнерів з плоским набором і плоскою картою [95][96]
  • Контекст без вирахування для розподільників у посібниках з вирахування контейнерів [97]
  • гетерогенні перевантаження стиранням для асоціативних контейнерів [98]
  • Дозвіл побудови пар ітераторів у стеку та черзі [99]
  • вимагаючи і бути тривіально скопійованим [100] std::spanstd::basic_string_view

Підтримка сумісності з мовою Сі

  • новий заголовок [101] <stdatomic.h>

Звіти про дефекти мови

  • Синтаксис ідентифікатора C++ з використанням Unicode Standard Annex 31 [102]
  • Дозвіл дублювання атрибутів [103]
  • Зміна області застосування типу повернення кінця лямбди [104]
  • Зменшення кількості перевантажених операторів порівняння [105]
  • Призначення незалежних сполучень volatile [106][107]
  • Фіксація сумісності та переносимості [108] char8_t
  • Пом'якшення вимог щодо відповідності існуючим практикам [109] wchar_t
  • Допускання деяких вказівок і посилань або невідомого походження в константних виразах [110] this
  • Впровадження негайно-реагуючих функцій, що переходять до безпосередніх функцій [111]
  • Дозволу у контекстах шаблонів без створення екземплярівstatic_assert(false)

Звіти про дефекти в бібліотеці

  • Зміни в бібліотеці діапазонів:
    • Умовно запозичені діапазони [112]
    • Налагодження адаптерів та вхідного діапазону [113] std::counted_iterator
    • Послаблення обмеження [114] std::ranges::join_view
    • Перейменовано на нове [115] std::ranges::split_viewstd::ranges::lazy_split_viewsplit_view
    • Видалено обмеження з концепції [116] std::default_initializablestd::ranges::view
    • Переглянуто з правом власності та новим [117] std::ranges::owning_view
    • [118] std::ranges::istream_view
  • Зміни в бібліотеці форматування тексту:
    • std::basic_format_string [119]
    • Перевірка рядків формату під час компіляції
    • зменшення розміру двійкового коду [120] std::format_to
    • Виправлення локальної обробки у форматувальниках chrono [121]
    • Вдосконалення оцінки ширини [122] та допусків до символів заповнення [123] std::format
    • Використання посилань на посилання в аргументах формату для дозволу , які не є формату const [124]
  • Повністю і [125] constexprstd::variantstd::optional
  • Підтримуваних типів , похідних від [126] std::variantstd::visit

Вилучені функції та застарілість

Видалені функції:

  • Підтримка збору сміття та виявлення витоків на основі досяжності. Вона була додана до стандарту, починаючи з C++11, але жоден компілятор не підтримує цю функцію до C++23. [127]
  • Змішана широка рядкова літеральна конкатенація. [128]
  • Широкосимвольні літерали без кодування та багатосимвольні широкосимвольні літерали. [129]

Застарілі функції:

  • std::aligned_storage і [130] std::aligned_union
  • std::numeric_limits::has_denorm [131]

Скасовано застарілі функції:

  • Використання оператора коми в підрядкових виразах більше не вважається застарілим, але семантика була змінена для підтримки перевантажуваного n-adic .operator[]
  • C headers (відповідні заголовки для сумісності з C)<*.h>

Опубліковано як Технічні характеристики

  • Паралелізм TS v2 [132]

Підтримка компілятора

  • Clang поступово додав часткову підтримку C++23 з 2021 року у версії 13 до версії 18 у 2024 році, доступну через опцію . [133]-std=c++23
  • GCC додав часткову, експериментальну підтримку C++23 у 2021 році у версії 11 через опцію або Він також має можливість увімкнути розширення GNU на додаток до експериментальної підтримки C++23, .[134] -std=c++2b-std=c++23-std=gnu++2b

Історія

За відсутності очних зустрічей WG21 після кількох віртуальних засідань WG21 були застосовані наступні зміни, де вони були затверджені шляхом опитування.[9]

Після віртуального засідання WG21 9 листопада 2020 року, де вони були затверджені шляхом спрощених опитувань, були додані наступні: [135]

  • Літеральні суфікси для і відповідний знаковий типstd::size_t
  • Функція-елемент для і , щоб перевірити, чи містить рядок заданий підрядок або символcontainsstd::basic_stringstd::basic_string_view
  • Бібліотека stacktrace (), заснована на Boost. Трасування стека<stacktrace>
  • Типова ознака std::is_scoped_enum
  • Заголовок , для сумісності з атомами C<stdatomic.h>Після віртуального засідання WG21 22 лютого 2021 року додаються такі функції, де вони були схвалені шляхом спрощених опитувань: [136]
  • Видалення непотрібного порожнього списку параметрів з лямбда-виразів.()
  • Ремонт адаптерів вхідного діапазону та .counted_iterator
  • Пом'якшити вимоги до .[137] time_point::clock
  • std::visit для класів, які є похідними від . std::variant
  • Замки, замки, що замикаються. [138]
  • Умовно запозичені діапазони.
  • std::to_underlying.

Після літнього віртуального засідання 2021 року за стандартами ISO C++ у червні 2021 року нові функції та звіти про дефекти були затверджені шляхом спрощених опитувань: [139]

  • Продовжити, якщо ().if consteval
  • Звуження контекстних перетворень до .bool
  • Дозвіл дублювання атрибутів.
  • std::span-based string-stream ().<spanstream>
  • std::out_ptr() і.std::inout_ptr()
  • constexpr для , та .std::optionalstd::variant std::type_info::operator==
  • Ітератори об'єднують конструктори для (стек) і (черга).std::stackstd::queue
  • Декілька змін у бібліотеці діапазонів:
    • Узагальнені і для довільних діапазонів.starts_withends_with
    • Перейменовано на і створено нове .split_view,lazy_split_view,split_view
    • Послаблення обмеження на .join_view
    • Зняття обмежень з поняття .default_initializableview
    • Конструктор діапазонів для .std::basic_string_view
  • Заборона і будівництво з нуля .std::basic_stringstd::basic_string_view
  • std::invoke_r.
  • Удосконалення на .std::format
  • Додавання аргументів за замовчуванням для конструктора пересилання.std::pair

Після осіннього віртуального засідання 2021 року за стандартами ISO C++ у жовтні 2021 року нові функції та звіти про дефекти були затверджені спрощеними опитуваннями:[140]

  • Нелітеральні змінні, мітки та goto у функціях, але все ще погано сформовані для їх обчислення під час компіляції.constexpr
  • Явно вказано параметр об'єкту this
  • Зміни в наборах символів і кодуваннях.
  • Нові препроцесори: і . Обидві директиви були додані в C23 (оновлення мови C) і GCC 12. [141] #elifdef #elifndef
  • Дозволено оголошення псевдонімів у виразах ініціалізації.
  • Перевантаження багатовимірного підіндексного оператора (наприклад, ).arr[1, 2]
  • Копія розпаду в мові: або .auto(x)auto{x}
  • Зміни в бібліотеці форматування тексту:
    • Виправлення локалізованої обробки у форматувальниках chrono.
    • Використання посилань на посилання в аргументах типів для дозволу накшталт .std::generator
  • Додавання псевдоніма типу, який еквівалентний .[142] std::pmr::stacktracestd::basic_stacktrace<std::pmr::polymorphic_allocator>
  • Зміни в бібліотеці діапазонів:
    • Уточнене визначення виду.
    • Заміна шаблону функції на шаблони псевдонімів , , та об'єкта точки налаштування .std::ranges::istream_viewstd::ranges::istream_viewstd::ranges::wistream_viewstd::views::istream
    • zip Сімейство адаптерів діапазону:
      • zip_view
      • zip_transform_view
      • adjacent_view (і є еквівалентом std::views::pairwisestd::views::adjacent<2>)
      • adjacent_transform_view (і є еквівалентом std::views::pairwise_transformstd::views::adjacent_transform<2>)
  • std::move_only_function.
  • Одинарні операції для .std::optional
  • Шаблон функції-елемента .std::basic_string::resize_and_overwrite
  • Друк volatile покажчиків ().volatile T*
  • std::byteswap.
  • Неоднорідні перевантаження стиранням для асоціативних контейнерів.
  • Будь-яка спеціалізація і тривіально копіюється.std::spanstd::basic_string_view
  • Додавання умовних специфікацій до .[143] noexcept std::exchange
  • Оновлено специфікацію та використання цілочисельних типів класів. [144]
  • Уточнено заголовки C. "Заголовки не корисні в коді, який потрібен лише для того, щоб бути валідним C++. Таким чином, заголовки C повинні бути надані стандартною бібліотекою C++ як повністю підтримувана, а не застаріла частина, але їх також слід не рекомендувати використовувати в коді, який не є поліглотським кодом сумісності. [..] Ця пропозиція робить заголовки C більше не застарілими, тому немає формальної загрози майбутнього видалення. Ефективне знеохочення до використання заголовків C у чистому коді C++ тепер чітко прописано як нормативне знеохочення». [145]

Після віртуального засідання WG21 7 лютого 2022 року додаються такі функції, де вони були схвалені спрощеними опитуваннями: [146]

  • Дозволені атрибути оператора виклику функцій лямбди
  • std::expected
  • constexpr for та cmathcstdlib
  • Функція позначення недоступного коду
  • ranges::to
  • Ознака типу для виявлення прив'язки посилань до тимчасового типу
  • Робить std::unique_ptr constexpr
  • Підтримка міжпроцесних зв'язків (pipe) для адаптерів із заданим користувачем діапазоном
  • ranges::iotaі ranges::shift_leftranges::shift_right
  • views::join_with
  • Адаптери віконного діапазону: та views::chunkviews::slide
  • views::chunk_by

Після віртуального засідання WG21 25 липня 2022 року додаються такі функції та звіти про дефекти, де вони були затверджені спрощеними опитуваннями: [147]

  • Зроблено переписування рівності у виразах менш кардинальною зміною.
  • Скасовано застарілість побітового присвоєння змінним.volatile
  • Додано директиву препроцесора.#warning
  • Видалено широкі символьні літерали, які не підлягають кодуванню, та багатосимвольні широкосимвольні літерали.
  • Дозволено створювати в кінці складених операторів.
  • Додано екрановані послідовності, відокремлені фігурними дужками для вісімкових та шістнадцяткових чисел та універсальними назвами символів.
  • Дозволено, щоб функції ніколи не були константними виразами.constexpr
  • Спрощено деякі неявні правила переміщення з C++20 та дозволено неявне переміщення при поверненні посилання rvalue.
  • Додано спосіб задання символів юнікоду за іменем. Наприклад U'\N{LATIN CAPITAL LETTER A WITH MACRON}' // Equivalent to U'\u0100'
  • Дозволено operator() та lambda бути статичними.
  • Дозволено створювати покажчик та посилання невідомого походження у константних виразах this
  • Дозволено визначати в реалізації розширені типи з плаваючою комою на додаток до трьох стандартних типів з плаваючою комою. Додано псевдоніми типів , , , , для цих розширених типів, доступних через заголовок, їх відповідні літеральні суфікси або та додано перевантаження до різних стандартних функцій бібліотеки, які приймають числа як аргументи. std::float16_t std::float32_t std::float64_t std::float128_t std::bfloat16_t <stdfloat> f16 f32 f64 f128 bf16 F16 F32 F64 F128 BF16
  • Додано атрибут, який дозволяє компілятору припустити, що наданий вираз є істинним, щоб дозволити оптимізацію.[[assume(expression)]]
  • Обов'язковою зроблено підтримку вихідних файлів UTF-8, що забезпечує переносне кодування вихідних файлів.
  • Дозволено ініціалізовувати масиви та рядкові літерали UTF-8.char unsigned char
  • Видалено вимогу про те, що wchar_t може кодувати всі символи розширеного набору символів, фактично дозволяючи використовувати UTF-16 для широких рядкових літералів.
  • Додано представлення багатовимірного масиву, аналогічно .std::mdspan std::span
  • flat_map і були додані до Стандартної бібліотеки.flat_set
  • Додано функції та функції для друку форматованого тексту до стандартного виведення.std::print std::println
  • Надано іменовані модулі та для імпорту стандартну бібліотеку.std std.compat
  • Додано підтримку ексклюзивного режиму , аналогічного прапорцю "x" у форматі .fstreams fopen
  • Дозволено обробляти діапазони, кортежі та інші контейнери.std::format
  • Додано.std::forward_like
  • Зроблено використовувати семантику руху.std::string::substr
  • Додано, що реалізує генератор співпрограм, який моделює std::generatorstd::ranges::input_range
  • views::cartesian_product, , , , .views::repeatviews::strideviews::as_constviews::as_rvalue
  • Додано нові алгоритми: , , та алгоритми згортання діапазонів.ranges::find_lastranges::contains
  • Зроблено сумісним з іншими кортежними об'єктами.std::tuple
  • Явне управління життєвим часом для неявних типів.
  • Зроблені та інтегральні перевантаження та -сумісні.std::bitsetstd::to_charsstd::from_charsconstexpr
  • Додавання типів лише з рухом підтримує концепції порівняння.
  • Діапазони ітераторів як входи для алгоритмів, що не мають діапазонів.
  • Адаптери звільненого діапазону для використання лише руху.

Після засідання гібридної WG21 7 листопада 2022 року додаються такі функції та звіти про дефекти, де вони були затверджені спрощеними опитуваннями:[148]

  • Допускається бути .operator[]static
  • Дозволені та thread_local змінні з'являтися у функціях, якщо вони використовуються в константних виразах.static constexpr
  • consteval поширюється вгору, тобто певні існуючі функції стають функціями, коли ці функції можуть бути викликані вже під час компіляції.constexprconsteval
  • Збільшено час життя тимчасових символів, які з'являються в for-range ініціалізаторі циклу на основі діапазону, щоб покрити весь цикл.for
  • Скасовано застарілість (усіх, а не лише побітових) присвоєння сполук змінним.volatile
  • Одинарні функції для .std::expected
  • Синхронізуйте вихідні дані з базовим потоком, якщо використовується рідний API Unicode. [149] std::print

Після фінального засідання гібридної WG21 6-11 лютого 2023 року додаються такі функції та звіти про дефекти, де вони були затверджені солом'яними опитуваннями: [150]

  • Посилання на стандарт Unicode. [151]
  • Приховані ітератори для належного зведення. [152]
  • views::enumerate
  • Створення багатопараметричних конструкторів представлень явними
  • Звільнені полігони просто дрібниця
  • Уникнено покращень у std::format
  • Удосконалено оцінку шириниstd::format
  • std::format Заповненння символьними дозволами
  • Форматування та thread::idstacktrace
  • Типова ознака std::is_implicit_lifetime
  • std::common_reference_t має бути еталонним типомstd::reference_wrapper
  • Заборонено спеціалізацію користувача на std::allocator_traits
  • std::pmr::generator
  • Заборонено std::numeric_limits::has_denorm
  • std::barrierгарантії завершення етапу

Див. також

Примітки

  1. ↑ Working Draft, Standard for Programming Language C++ (PDF). 10 травня 2023.
  2. ↑ N4951 Editors' Report: Programming Languages - C++. 10 травня 2023. Архів оригіналу за 5 червня 2023.
  3. ↑ Dusíková, Hana (6 листопада 2019). N4817: 2020 Prague Meeting Invitation and Information (PDF). Архів (PDF) оригіналу за 29 грудня 2019. Процитовано 13 лютого 2020.
  4. ↑ Voutilainen, Ville (25 листопада 2019). To boldly suggest an overall plan for C++23. www.open-std.org. Архів оригіналу за 24 грудня 2019. Процитовано 13 лютого 2020.
  5. ↑ P2145R0: Evolving C++ Remotely. www.open-std.org.
  6. ↑ а б Sutter, Herb (29 липня 2020). Business Plan and Convener's Report: ISO/IEC JTC1/SC22/WG21 (C++) (PDF).
  7. ↑ а б в Upcoming Meetings, Past Meetings : Standard C++. isocpp.org.
  8. ↑ C++23 "Pandemic Edition" is complete (Trip report: Winter ISO C++ standards meeting, Issaquah, WA, USA). herbsutter.com. 13 лютого 2023.
  9. ↑ ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee - ISOCPP. www.open-std.org. Процитовано 1 листопада 2024.