Komitet ISO pre štandardizáciu jazyka C++ schválil konečnú verziu špecifikácie, ktorá vytvára medzinárodný štandard „C++26“. Predložené možnosti v špecifikácii sú čiastočne už podporované v kompilátoroch GCC, Clang a Microsoft Visual C++. Podporujúce štandardné knižnice C++26 sú implementované v rámci projektu Boost.
V nasledujúcich dvoch mesiacoch bude schválená špecifikácia v príprave na publikáciu, počas ktorej sa vykoná redakčná úprava pravopisných chýb a preklepov. Na začiatku novembra bude výsledná verzia dokumentu zaslaná do ISO na publikáciu pod formálnym menom ISO/IEC 14882:2026.
Hlavné vlastnosti C++26:
- Boli implementované prvky zmluvného programovania (Contracts), ktoré umožňujú definovať formálne špecifikácie rozhraní pomocou troch nových operátorov: pre (predpoklad), post (požiadavka po) a contract_assert (overenie tvrdenia). Operátor „pre“ určuje predpoklady, ktoré musia byť splnené pred volaním (kontrola vstupných údajov); „post“ — podmienky, ktoré musia byť dodržané po vykonaní (požiadavky na výstupné údaje); contract_assert — podmienky vzniku výnimiek. Možnosť sa objaví v GCC 16. int f(const int x) pre (x != 1) // požiadavky na vstupné údaje post (r : r == x && r != 2) // požiadavky na výsledok; r — hodnota s výsledkom { contract_assert (x != 3); return x; }
- Bola pridaná podpora reflexie (Reflection), ktorá umožňuje sledovať a modifikovať prvky programu počas fázy kompilácie. Boli pridané nové operátory „^^“ pre získavanie meta-informácií o gramatickej konštrukcii a „[:…:]“ pre vykonávanie spätnej transformácie. Na transformáciu a spracovanie získaných informácií pri inšpekcii bola navrhnutá knižnica std::meta a sú dostupné možnosti ako výpočty s konštantami. Podpora reflexie bude pridaná v 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’ a ‘j’ majú rôzne hodnoty. static_assert(constant_of(^^i) == constant_of(^^j)); // ‘i’ a ‘j’ sú rovnaké static_assert(^^i != std::meta::reflect_constant(42)); // líši sa od hodnoty 42
- Pridaný operátor „template for“ na iteráciu cez prvky, ako sú balíky parametrov, podobné tuple objekty a výsledky reflexie (metaobjekty), v štádiu kompilácie štýlom bežnej slučky. Pri vykonaní „template for“ sa telo slučky rozbaľuje pre každý prvok a každá iterácia sa spracováva v samostatnej oblasti viditeľnosti, v ktorej sa meniteľná v slučke premenná považuje za konštantu. V kontexte reflexie sa „template for“ môže použiť na prehliadanie vlastností tried alebo výčtov. Možnosť sa objaví v GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } bude rozbalené do: 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); } } }
- Pridaný rámec std::execution pre asynchrónne a paralelné vykonávanie kódu. Poskytujú sa objekty scheduler, definujúci plánovač vykonávania úloh (vlákno, zásobník vlákien, GPU, event loop), sender, definujúci vykonávanú prácu, a receiver — spracovateľ výsledku. 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();
- Pridaná knižnica std::simd na paralelizáciu vykonávania operácií nad údajmi pomocou súborov inštrukcií SIMD, ako sú AVX-512 a NEON, s použitím štandardného systému typov 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;
- Navrhnutá implementácia vektora (polia) s variabilnou veľkosťou std::inplace_vector, umiestneného na zásobníku, ktorého veľkosť sa určuje v štádiu kompilácie. API je blízke std::vector, ale prvky poľa sú uložené nie v „hromade“, ale priamo v objekte. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
- Pridaná direktíva „#embed“, určená na vkladanie binárnych zdrojov do kódu. const unsigned char icon_display_data[] = { #embed "art.png" };
- Pridaná podpora na generovanie a spracovanie výnimiek pri chybách v kontexte constexpr na úrovni kompilácie. 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); }
- Implementovaná dátová štruktúra std::hive pre neusporiadané úložisko dát a zabezpečenie opätovného použitia pamäte uvoľnenej po odstránených prvkoch. Štruktúra je optimalizovaná pre záťaže s vysokou intenzitou pridávania a odstraňovania prvkov v ľubovoľnom poradí. Na rozdiel od polí, odstránenie prvku v std::hive nezpôsobuje posun ostatných prvkov, ale vedie k označeniu odstráneného prvku ako prázdneho, pričom následné vyplnenie uvoľnenej pozície sa vykonáva pri pridávaní nového prvku.
- Pridaná knižnica std::linalg s API pre lineárnu algebru, založená na BLAS.
- Pridaná podpora mechanizmu synchronizácie Hazard pointer, ktorý umožňuje zabrániť uvoľneniu pamäte objektov, s ktorými sa naďalej pracuje v iných vláknach, bez zamykania. Pri odstránení objektu je len označený ako odstránený, ale pamäť obsadená objektom sa uvoľňuje až keď všetky vlákna zrušia hazard-pointer nastavený počas práce s objektom.
- Pridaná podpora mechanizmu synchronizácie RCU (Read-Copy Update) — pri zápisových operáciách sa vytvára nový príklad objektu, pričom čítacie operácie nie sú zablokované a pokračujú v práci so starým príkladom. Po dokončení zmien sa nový príklad stáva aktívnym a nové čítacie operácie sa uskutočňujú s ním, zatiaľ čo starý príklad sa odstraňuje po dokončení jeho čítania vonkajšími vláknami.
- Boli vykonané zmeny na posilnenie bezpečnosti štandardnej knižnice, ako sú kontroly prijateľných hodnôt a pretečenia pamäte. Napríklad, pri prístupe k prvku „constexpr reference operator[](size_type idx) const;“ sa pridáva kontrola podmienky „idx < size()".
- Poskytla sa možnosť použitia kľúčového slova „constexpr“ s variantom operátora „new“ (placement new) na umiestnenie objektu do vopred alokovanej pamäte počas kompilácie.
- Pridaná podpora štruktúrovaných viazaní (structured binding) v kontexte „constexpr“, teda odkazy na konštantné výrazy môžu byť teraz samy o sebe konštantnými výrazmi. Podpora bola implementovaná pre polia a jednoduché štruktúry. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
- Do štruktúrovaných viazaní bola pridaná možnosť používať syntax „…“ na určenie balíkov (pack), zachytávajúcich zostávajúci počet prvkov z priraďovacej sekvencie. auto [x,y,z] = f(); \/\/ do premenných x, y, z budú zapísané tri prvky, ktoré vrátila f(). auto […xs] = f(); \/\/ do balíka xs budú zapísané všetky prvky, ktoré vrátila f(). auto [x, …rest] = f(); \/\/ V x bude zapísaný prvý prvok, a v rest – zostávajúce. auto [x, y, …rest] = f(); \/\/ V x bude zapísaný prvý prvok, v y – druhý, a v rest – tretí. auto [x, …rest, z] = f(); \/\/ do x – prvý, do rest – druhý, do z – tretí.
- Pridaná podpora „triviálnej presunovateľnosti“ typov (Trivial Relocatability), ktorá umožňuje optimalizovať presuny objektov daného typu cez ich klonovanie v pamäti bez volania konštruktorov alebo deštruktorov. Pre triedy boli implementované vlastnosti memberwise_trivially_relocatable a memberwise_replaceable, a pre nízkoúrovňové presúvanie jedného alebo viacerých objektov boli pridané funkcie trivially_relocate_at a trivially_relocate.
- Implementovaná podpora pripojenia funkcie main() k globálnemu modulu a definovania funkcie main() v pomenovaných moduloch.
- Pridaný variabilný operátor „friend“ („friend Ts…“).
- Realizované atribúty pre štruktúrované viazania;
- Pridaná syntax ‘= delete(„príčina“)’.
- Do základného súboru symbolov boli pridané „@“, „$“ a „`“.
- Poskytnutá možnosť uplatniť štruktúrované viazanie (structured binding) ako podmienku v operátoroch if a switch.
- Pridaná možnosť používať viacero premenných-náhradníkov s menom „_“ v jednom rozsahu platnosti, napríklad, teraz sú správne konštrukcie: struct S { int _, _; }; void func() { int _, _; } void other() { int _; \/\/ predtým sa zobrazovala výstraha v režime -Wunused }
- Zaviedla sa možnosť používania reťazcových literálov v kontexte, v ktorom sa nepoužívajú na inicializáciu poľa znakov a nezapadajú do výsledného kódu, ale aplikujú sa len počas kompilácie na diagnostické správy a preprocesing, napríklad ako parametre direktív a atribútov _Pragma, asm, extern, static_assert, [[deprecated]] a [[nodiscard]].
- Pridané vstavané funkcie: „__builtin_is_within_lifetime“ na kontrolu aktivity alternatívy v uniach (union) a „__builtin_is_virtual_base_of“ na kontrolu, či je základná trieda virtuálna.
- Realizované triviálne nekonečné cykly bez nedeterministického správania.
- Zabezpečený výstup chyby pri odstránení ukazovateľa na neúplný typ.
- Vyhlásený za zastaraný syntax definovania variabilných parametrov s trochou bez predchádzajúcej čiarky (napríklad, keď sa uvádza „void e(int…)“ namiesto „void e(int, …)“).
- Zakázané používanie makier na vyhlásenie modulov.
- Prevedené do kategórie zastaraných vykonávanie implicitných konverzií enumerovaných hodnôt v aritmetických výpočtoch. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // zastarané int k = f - e; // zastarané int x = +f - e; // OK }
- Ukončená podpora priameho porovnávania polí. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
- Vyhlásený za zastaraný šablónový trieda is_trivial.
Zdroj: opennet.ru
