Одобрен е стандартът C++26

ISO комитетът за стандартизация на езика C++ завърши окончателната версия на спецификацията, образуваща международния стандарт „C++26“. Представените в спецификацията възможности частично вече са поддържани в компилаторите GCC, Clang и Microsoft Visual C++. Стандартните библиотеки, поддържащи C++26, са реализирани в рамките на проекта Boost.

През следващите два месеца одобрената спецификация ще премине през етап на подготовка на документа за публикуване, на който ще бъде извършена редакция за правописни грешки и печатни грешки. В началото на ноември окончателният вариант на документа ще бъде изпратен в ISO за публикуване със формалното име ISO/IEC 14882:2026.

Основни характеристики на C++26:

  • Реализирани са елементи на контрактно програмиране (Contracts), позволяващи определяне на формални спецификации на интерфейсите с помощта на три нови оператора: pre (предусловие), post (постусловие) и contract_assert (проверка на твърдение). Операторът „pre“ определя предварителните условия, които трябва да бъдат изпълнени преди извикването (проверка на входните данни); „post“ — условията, които трябва да се спазват след изпълнението (изисквания към изходните данни); contract_assert — условията за възникване на изключения. Възможността ще бъде налична в GCC 16. int f(const int x) pre (x != 1) // изисквания към входните данни post (r : r == x && r != 2) // изисквания към резултата; r — стойността с резултата { contract_assert (x != 3); return x; }
  • Добавена е поддръжка на рефлексия (Reflection), позволяваща проследяване и модифициране на елементите на програмата на етапа на компилация. Добавени са нови оператори „^^“ за получаване на метаинформация за граматичната конструкция и „[:…:]“ за извършване на обратна трансформация. За преобразуване и обработка на получената информация по време на инспекция е предложена библиотека std::meta, като са налични възможности за изчисления с константи. Поддръжката на рефлексия ще бъде добавена в GCC 16. constexpr int i = 42, j = 42; constexpr std::meta::info r = ^^i, s = ^^i; static_assert(r == r && r == s); static_assert(^^i != ^^j); // ‘i’ и ‘j’ имат различни стойности. static_assert(constant_of(^^i) == constant_of(^^j)); // ‘i’ и ‘j’ са равни static_assert(^^i != std::meta::reflect_constant(42)); // различава се от стойността 42
  • Добавен операторът „template for“ за преглед на елементи, като параметрични пакети, подобни на кортежи обекти и резултати от рефлексия (метаобекти), на етапа на компилация в стил на обикновен цикъл. При изпълнението на „template for“ тялото на цикъла се разкрива за всеки елемент и всяка итерация се обработва в отделна област на видимост, в която променливата, променяща се в цикъла, е константа. В контекста на рефлексията „template for“ може да се използва за обход на свойства на класове или изброявания. Функционалността ще бъде налична в GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } ще бъде разкрито в: void f() { { constexpr auto&& __range = std::array{1, 2, 3}; constexpr auto __begin = __range.begin(); constexpr auto __expansion-size = __range.end() — __begin; // 3 { constexpr int I = *(__begin + 0); static_assert(I < 4); } { constexpr int I = *(__begin + 1); static_assert(I < 4); } { constexpr int I = *(__begin + 2); static_assert(I < 4); } } }
  • Добавен е фреймуъркът std::execution за асинхронно и паралелно изпълнение на код. Предоставят се обекти scheduler, който определя планировчика за изпълнение на задачите (нишка, пул от нишки, GPU, цикъл на събития), sender, който определя извършваната работа, и receiver — обработчик на резултата. using namespace std::execution; scheduler auto sch = thread_pool.scheduler(); sender auto begin = schedule(sch); sender auto hi = then(begin, []{ std::cout < "Hello world! Have an int."; return 13; }); sender auto add_42 = then(hi, [](int arg) { return arg + 42; }); auto [i] = this_thread::sync_wait(add_42).value();
  • Добавена е библиотеката std::simd за паралелно изпълнение на операции върху данни с помощта на инструкции SIMD, като AVX-512 и NEON, с използване на стандартната система от типове C++. std::simd a = {1.0f, 2.0f, 3.0f, 4.0f}; std::simd b = {5.0f, 6.0f, 7.0f, 8.0f}; std::simd result = a + b;
  • Предложена е реализация на вектор (масив) с променлив размер std::inplace_vector, който се разполага в стека и чийто размер се определя на етапа на компилация. API-то е близко до std::vector, но елементите на масива не се съхраняват в „купка“, а вътре в обекта. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
  • Добавена е директивата „#embed“, предназначена за вграждане в кода на бинарни ресурси. const unsigned char icon_display_data[] = { #embed "art.png" };
  • Добавена поддръжка за генериране и обработка на изключения на етапа на компилация при грешки в контекста constexpr. constexpr std::optional checked_divide(unsigned n, unsigned d) { try { return divide(n, d); } catch (…) { return std::nullopt; } } constexpr date parse_date(std::string_view input) { auto [correct, year, month, day] = ctre::match(input); if (!correct) { throw incorrect_date{input}; } return build_date(year, month, day); }
  • Реализирана е структура от данни std::hive за неупорядочено съхранение на данни и осигуряване на повторно използване на паметта, освободена след изтриване на елементи. Структурата е оптимизирана за натоварвания с висока интензивност на добавяне и изтриване на елементи в произволен ред. В отличие от масивите, изтриването на елемент в std::hive не причинява преместване на други елементи, а води до маркиране на изтрития елемент като празен с последващо запълване на освободената позиция при добавяне на нов елемент.
  • Добавена е библиотеката std::linalg с API за линейна алгебра, основана на BLAS.
  • Добавена е поддръжка на механизма за синхронизация Hazard pointer, позволяващ да се предотврати освобождаването на паметта на обектите, с които продължава работа в други потоци, без поставяне на блокировки. При изтриване на обект той просто се маркира като изтрит, но заетата от обекта памет се освобождава само когато всички потоци свалят hazard-указателя, поставен по време на работа с обекта.
  • Добавена е поддръжка на механизма за синхронизация RCU (Read-Copy Update) – при операции на запис се създава нов екземпляр на обекта, а операциите на четене не са блокирани и продължават да работят със стария екземпляр. След приключване на промяната новият екземпляр става активен и новите операции на четене вече се извършват с него, а старият екземпляр се изтрива след приключване на четящите потоци.
  • Внесени са промени за усилване на сигурността на стандартната библиотека, като проверки за допустими стойности и излизане извън границите на буфера. Например, при достъп до елемент «constexpr reference operator[](size_type idx) const;» се добавя проверка на условието «idx < size()».
  • Предоставена е възможност за използване на ключовата дума «constexpr» с разновидността на оператора «new» (placement new) за разполагане на обект в предварително заделена памет по време на компилацията.
  • Добавена поддръжка на структурирани връзки (structured binding) в контекста на «constexpr», т.е. препратките към константни изрази сега могат да бъдат константни изрази. Поддръжката е реализирана за масиви и прости структури. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
  • В структурирани връзки е добавена възможността за използване на синтаксиса «…» за указание на пакети (pack), които улавят останалото число елементи от присвояваната последователност. auto [x,y,z] = f(); // в променливите x, y, z ще бъдат записани три елемента, върнати от f(). auto […xs] = f(); // в пакета xs ще бъдат записани всички елементи, върнати от f(). auto [x, …rest] = f(); // В x ще бъде записан първият елемент, а в rest — останалите. auto [x, y, …rest] = f(); // В x ще бъде записан първият елемент, в y — вторият, а в rest — третият. auto [x, …rest, z] = f(); // в x — първият, в rest — втория, в z — третия.
  • Добавена е поддръжка на «тривиална преносимост» на типове (Trivial Relocatability), позволяваща оптимизиране на преместванията на обекти от зададен тип чрез клониране в паметта без извикване на конструкции или деструктори. За класове са реализирани свойствата memberwise_trivially_relocatable и memberwise_replaceable, а за нискоуровневото преместване на един или няколко обекта са добавени функции trivially_relocate_at и trivially_relocate.
  • Реализирана е поддръжка за прикрепване на функция main() към глобален модул и дефиниране на функция main() в именувани модули.
  • Добавен е вариативен оператор «friend» («friend Ts…»).
  • Реализирани са атрибути за структурирани връзки;
  • Добавен е синтаксис ‘= delete(«причина»)’.
  • В основния набор символи са включени «@», «$» и «`».
  • Предоставена е възможност за прилагане на структурирано свързване (structured binding) като условие в операторите if и switch.
  • Добавена е възможност за използване на няколко променливи-попълнители с името «_» в една област на видимост, например, сега са правилни конструкции: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // преди се издаваше предупреждение в режим -Wunused }
  • Възможността да се използват текстови литерали в контексти, в които не се използват за инициализация на масиви от символи и не попада в резултатния код, а се използват само по време на компилация за диагностични съобщения и преработка, например, като параметри на директиви и атрибути _Pragma, asm, extern, static_assert, [[deprecated]] и [[nodiscard]].
  • Добавени са вградени функции: «__builtin_is_within_lifetime» за проверка на активността на алтернативи в обединения (union) и «__builtin_is_virtual_base_of» за проверка дали базовият клас е виртуален.
  • Реализирани са тривиални безкрайни цикли без неопределено поведение.
  • Осигурен е изход на грешка при изтриване на указател на непълен тип.
  • Обявен за остарял синтаксисът на определение на променливи параметри с многоточие без предшестваща запетая (например, когато се указыва „void e(int…)“ вместо „void e(int, …)“).
  • Забранено е използването на макроси за обявяване на модули.
  • Преведено е на ниво остарели неявни преобразувания на изброявани стойности в математически изчисления. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // остаряло int k = f - e; // остаряло int x = +f - e; // ОК }
  • Прекратена е поддръжката на директно сравнение на масиви. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
  • Обявен за остарял шаблонен клас is_trivial.

    Източник: opennet.ru
Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster