Výbor ISO pro standardizaci jazyka C++ dokončil schválení finální verze specifikace, která tvoří mezinárodní standard „C++26“. Představené možnosti v specifikaci jsou částečně již podporovány v kompilátorech GCC, Clang a Microsoft Visual C++. Standardní knihovny podporující C++26 jsou implementovány v rámci projektu Boost.
V následujících dvou měsících bude schválená specifikace v procesu přípravy dokumentu k publikaci, během nějž proběhne redakční úprava pravopisných chyb a překlepů. Na začátku listopadu bude výsledná verze dokumentu zaslána ISO k publikaci pod formálním názvem ISO/IEC 14882:2026.
Hlavní rysy C++26:
- Byly implementovány prvky smluvního programování (Contracts), které umožňují definovat formální specifikace rozhraní pomocí tří nových operátorů: pre (předpoklad), post (postpodmínka) a contract_assert (ověření tvrzení). Operátor „pre“ definuje předpoklady, které musí být splněny před voláním (ověření vstupních dat); „post“ — podmínky, které musí být dodržovány po vykonání (požadavky na výstupní data); contract_assert — podmínky vzniku výjimek. Tato funkčnost se objeví v GCC 16. int f(const int x) pre (x != 1) // požadavky na vstupní data post (r : r == x && r != 2) // požadavky na výstup; r — hodnota s výsledkem { contract_assert (x != 3); return x; }
- Byla přidána podpora reflexe (Reflection), která umožňuje sledovat a měnit prvky programu ve fázi kompilace. Byly přidány nové operátory „^^“ pro získání metainformací o gramatické konstrukci a „[:…:]“ pro provádění zpětné transformace. Pro transformaci a zpracování informací získaných během inspekce byla navržena knihovna std::meta a jsou k dispozici možnosti, jako jsou výpočty s konstantami. Podpora reflexe bude přidána 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ůzné hodnoty. static_assert(constant_of(^^i) == constant_of(^^j)); // ‘i’ a ‘j’ jsou identické static_assert(^^i != std::meta::reflect_constant(42)); // liší se od hodnoty 42
- Byl přidán operátor „template for“ pro iteraci přes prvky, jako jsou parametrové balíčky, objekty podobné n-ticím a výsledky reflexe (metaobjekty) v době kompilace ve stylu běžné smyčky. Při spuštění „template for“ se tělo smyčky rozbalí pro každý prvek a každá iterace se zpracovává v samostatném rámci, ve kterém je proměnná měnící se v cyklu konstantní. V kontextu reflexe může být „template for“ použito k procházení vlastností tříd nebo výčtů. Tato funkcionalita se objeví v GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } bude rozbaleno 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); } } }
- Byl přidán rámec std::execution pro asynchronní a paralelní vykonávání kódu. Jsou k dispozici objekty scheduler, které určují plánovač vykonávání úloh (vlákno, vláknový pool, GPU, event loop), sender, který určuje vykonávanou práci, a receiver — zpracovatel výsledků. 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();
- Byla přidána knihovna std::simd pro paralelizaci vykonávání operací na datech pomocí sad instrukcí SIMD, jako jsou AVX-512 a NEON, s použitím standardního typu 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;
- Byla navržena implementace vektoru (pole) proměnné velikosti std::inplace_vector, umisťovaného na zásobník, jehož velikost je určena v době kompilace. API je blízké std::vector, ale prvky pole jsou uloženy nikoli na „hromadě“, ale uvnitř objektu. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
- Byla přidána direktiva „#embed“, určená k vkládání binárních prostředků do kódu. const unsigned char icon_display_data[] = { #embed "art.png" };
- Byla přidána podpora generování a zpracování výjimek během kompilace v případě chyb v kontextu 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); }
- Byla implementována datová struktura std::hive pro neuspořádané ukládání dat a zajištění opětovného využití paměti, kterou uvolnily odstraněné prvky. Struktura je optimalizována pro zatížení s vysokou intenzitou přidávání a odstraňování prvků v libovolném pořadí. Na rozdíl od polí, odstranění prvku ve std::hive nezpůsobuje posunutí ostatních prvků, ale pouze označení odstraněného prvku jako prázdného s následným naplněním uvolněné pozice při přidání nového prvku.
- Byla přidána knihovna std::linalg s API pro lineární algebru, založená na BLAS.
- Byla přidána podpora synchronizačního mechanismu Hazard pointer, který umožňuje bez zavádění zámků zabránit uvolnění paměti objektů, se kterými se stále pracuje v jiných vláknech. Při odstranění objektu je pouze označen jako odstraněný, ale paměť obsazená objektem je uvolněna až poté, co všechna vlákna odstraní hazard pointer, který byl zaveden během práce s objektem.
- Byla přidána podpora synchronizačního mechanismu RCU (Read-Copy Update) — při zápisových operacích se vytváří nová instance objektu, a čtecí operace nejsou blokovány, ale pokračují ve práci se starou instancí. Po dokončení změny se nová instance stává aktivní a nové čtecí operace již probíhají s ní, zatímco stará instance je odstraněna po dokončení čtení vlákny, které s ní pracovaly.
- Byly provedeny změny na posílení bezpečnosti standardní knihovny, jako jsou kontroly povolených hodnot a překročení hranic bufferu. Například při přístupu k prvku „constexpr reference operator[](size_type idx) const;“ je přidána kontrola podmínky „idx < size()“.
- Byla poskytnuta možnost použití klíčového slova „constexpr“ s variantou operátoru „new“ (placement new) pro umístění objektu do předem alokované paměti během kompilace.
- Byla přidána podpora strukturovaného vázání (structured binding) v kontextu 'constexpr', tj. odkazy na konstantní výrazy mohou nyní být také konstantními výrazy. Podpora byla implementována pro pole a jednoduché struktury. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
- Do strukturovaného vázání byla přidána možnost použití syntaktického '...' pro specifikaci balíků (pack), které zachycují zbývající počet prvků z přiřazované sekvence. auto [x,y,z] = f(); // do proměnných x, y, z budou přiřazeny tři prvky vrácené f(). auto […xs] = f(); // do balíku xs budou přiřazeny všechny prvky vrácené f(). auto [x, …rest] = f(); // v x bude přiřazen první prvek, a v rest — ostatní. auto [x, y, …rest] = f(); // v x bude přiřazen první prvek, v y — druhý, a v rest — třetí. auto [x, …rest, z] = f(); // v x — první, v rest — druhý, v z — třetí.
- Byla přidána podpora 'triviální přemístitelnosti' typů (Trivial Relocatability), která umožňuje optimalizovat přesuny objektů daného typu jejich klonováním v paměti bez volání konstruktérů nebo destruktorů. Pro třídy byla realizována vlastnost memberwise_trivially_relocatable a memberwise_replaceable, a pro nízkoúrovňové přemisťování jednoho nebo více objektů byly přidány funkce trivially_relocate_at a trivially_relocate.
- Byla implementována podpora připojení funkce main() k globálnímu modulu a definice funkce main() v pojmenovaných modulech.
- Byl přidán variabilní operator 'friend' ('friend Ts…').
- Byly realizovány atributy pro strukturované vázání;
- Byl přidán syntaktický ' = delete("důvod")'.
- Do základní množiny znaků byly zahrnuty '@', '$' a '`'.
- Byla poskytnuta možnost použití strukturovaného vázání (structured binding) jako podmínky v operátorech if a switch.
- Byla přidána možnost použití více proměnných-zástupců s názvem '_' v jednom rozsahu, například nyní jsou platné konstrukce: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // dříve se zobrazovala výstraha v režimu -Wunused }
- Byla umožněna syntaktická forma řetězcových literálů v kontextu, kde nejsou používány pro inicializaci pole znaků a nedostanou se do výsledného kódu, ale jsou využívány pouze během kompilace pro diagnostické zprávy a předzpracování, například jako parametry direktiv a atributů _Pragma, asm, extern, static_assert, [[deprecated]] a [[nodiscard]].
- Byly přidány vestavěné funkce: „__builtin_is_within_lifetime“ pro kontrolu aktivity alternativy v unionech a „__builtin_is_virtual_base_of“ pro kontrolu, zda je základní třída virtuální.
- Byly implementovány triviální nekonečné smyčky bez nejednoznačného chování.
- Zajišťuje se zobrazení chyby při odstranění ukazatele na neúplný typ.
- Byla prohlášena za zastaralou syntaxe definice variabilních parametrů s třemi tečkami bez předchozí čárky (například, když je uvedeno „void e(int…)“ místo „void e(int, …)“).
- Použití makra pro deklaraci modulů je zakázáno.
- Bylo převedeno do skupiny zastaralých implicitních převodů typů výčtových hodnot v aritmetických výpočtech. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // zastaralé int k = f - e; // zastaralé int x = +f - e; // OK }
- Byla ukončena podpora přímého porovnání polí. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
- Byla prohlášena za zastaralou šablonová třída is_trivial.
Zdroj: opennet.ru
