ISO-komitéen for standardisering af C++-sproget har afsluttet den endelige version af specifikationen, der danner grundlaget for den internationale standard "C++26". De funktioner, der er præsenteret i specifikationen, understøttes delvist allerede i compilere som GCC, Clang og Microsoft Visual C++. Standardbiblioteker, der understøtter C++26, er implementeret inden for Boost-projektet.
I de næste to måneder vil den godkendte specifikation være i processen med at forberede dokumentet til offentliggørelse, hvor der vil blive arbejdet på redaktionel korrektur for stavefejl og typografiske fejl. I begyndelsen af november vil den endelige version af dokumentet blive sendt til ISO til offentliggørelse under det officielle navn ISO/IEC 14882:2026.
De vigtigste egenskaber ved C++26:
- Elementer af kontraktprogrammering (Contracts) er blevet implementeret, som gør det muligt at definere formelle specifikationer for interfaces ved hjælp af tre nye operatorer: pre (forudsætning), post (efterbetingelse) og contract_assert (bekræftelsescheck). Operatoren "pre" definerer de forudsætninger, der skal være opfyldt før kaldet (kontrol af input); "post" er de betingelser, der skal overholdes efter udførelsen (krav til output); contract_assert er betingelserne for undtagelser. Denne funktion vil være tilgængelig i GCC 16. int f(const int x) pre (x != 1) // krav til input post (r : r == x && r != 2) // krav til resultatet; r er resultatværdien { contract_assert (x != 3); return x; }
- Støtten til refleksion (Reflection) er blevet tilføjet, hvilket tillader overvågning og modificering af programmets elementer på compileringstidspunktet. Nye operatorer "^^" er blevet tilføjet til at hente metainformation om grammatiske konstruktioner og "[:…:]" til at udføre omvendt transformation. For at transformere og behandle den information, der er indhentet under inspektionen, er biblioteket std::meta blevet foreslået, og muligheder som beregning med konstanter er tilgængelige. Støtten til refleksion vil blive tilføjet i 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' og 'j' har forskellige værdier. static_assert(constant_of(^^i) == constant_of(^^j)); // 'i' og 'j' er ens static_assert(^^i != std::meta::reflect_constant(42)); // adskilt fra værdien 42
- Operatøren «template for» er blevet tilføjet for at iterere over elementer såsom parameterpakker, tuple-lignende objekter og refleksionsresultater (meta-objekter) under kompileringen i stil som en almindelig løkke. Ved udførelse af «template for» bliver løkkens krop udfoldet for hvert element, og hver iteration behandles i et separat syn, hvor løkkevariablen, der ændres, er en konstant. I refleksionskonteksten kan «template for» anvendes til at gennemgå egenskaber i klasser eller enumerationer. Muligheden vil være tilgængelig i GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } vil blive udfoldet til: 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-rammeværket er blevet tilføjet til asynkron og parallel udførelse af kode. Der leveres objekter scheduler, der definerer planlæggeren for opgaveudførelse (tråd, trådgruppe, GPU, begivenhedsløkke), sender, der definerer det arbejde, der udføres, og receiver, der er resultatbehandleren. 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();
- Biblioteket std::simd er blevet tilføjet for at parallelisere udførelsen af operationer på data ved hjælp af SIMD-instruktionssæt såsom AVX-512 og NEON, med standard typesystemet i 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;
- Implementeringen af vektoren (arrayet) std::inplace_vector, som er placeret på stakken med en størrelse defineret under kompileringen, er blevet foreslået. API'en ligner std::vector, men arrayets elementer opbevares ikke i ‘heap’en’, men inden i objektet. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
- Direktivet «#embed» er blevet tilføjet, som er beregnet til at indlejre binære resurser i koden. const unsigned char icon_display_data[] = { #embed "art.png" };
- Tilsupport for exception generation and handling at compile time when errors occur in the context of constexpr has been added. 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); }
- Data structure std::hive has been implemented for unordered data storage and memory reuse freed from deleted elements. The structure is optimized for workloads with high intensity of adding and removing elements in arbitrary order. Unlike arrays, removing an element in std::hive does not shift other elements but marks the removed element as empty, subsequently filling the freed position when a new element is added.
- The std::linalg library has been added with an API for linear algebra based on BLAS.
- Support for the Hazard pointer synchronization mechanism has been added, allowing for memory of objects that continue to be worked on in other threads to be prevented from being released without setting locks. When an object is deleted, it is only marked as deleted, but the memory occupied by the object is released only when all threads have cleared the hazard pointer set during operations on the object.
- Support for the RCU (Read-Copy Update) synchronization mechanism has been added — during write operations, a new instance of the object is created, and read operations are not blocked but continue to work with the old instance. After the modification is completed, the new instance becomes active and new read operations are performed with it, while the old instance is deleted after all reading threads have completed.
- Changes have been made to enhance the security of the standard library, such as checks for permissible values and buffer overflows. For example, when accessing the element «constexpr reference operator[](size_type idx) const;», a check is added for the condition «idx < size()".
- The ability to use the keyword «constexpr» with the variant of the «new» operator (placement new) for placing an object in pre-allocated memory during compilation has been provided.
- Der er tilføjet support for strukturerede bindinger (structured binding) i konteksten af "constexpr", dvs. referencer til konstante udtryk kan nu selv være konstante udtryk. Supporten er implementeret for arrays og enkle strukturer. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
- Der er tilføjet mulighed for at bruge syntaksen "..." i strukturerede bindinger til at angive pakker (pack), der fanger det resterende antal elementer fra den tildelte sekvens. auto [x,y,z] = f(); // tre elementer, der returneres af f(), vil blive gemt i variablerne x, y, z. auto [...xs] = f(); // alle elementer, der returneres af f(), vil blive gemt i pakken xs. auto [x, ...rest] = f(); // x får det første element, mens rest får de andre. auto [x, y, ...rest] = f(); // x får det første element, y får det andet, og rest får det tredje. auto [x, ...rest, z] = f(); // x får det første, rest får det andet, z får det tredje.
- Der er tilføjet support for "trivial relocatability" af typer (Trivial Relocatability), som muliggør optimering af flytningen af objekter af en given type ved at klone dem i hukommelsen uden at kalde konstruktører eller destruktører. For klasser er egenskaberne memberwise_trivially_relocatable og memberwise_replaceable implementeret, og til lavniveau-flytning af et eller flere objekter er funktionerne trivially_relocate_at og trivially_relocate tilføjet.
- Der er implementeret support til at knytte funktionen main() til den globale modul og definere funktionen main() i navngivne moduler.
- Der er tilføjet en variabel operator "friend" ("friend Ts...").
- Der er implementeret attributter til strukturerede bindinger;
- Der er tilføjet syntaksen ‘= delete(„årsag“)‘.
- Symbollisten har fået tilføjet „@“, „$“ og „`“.
- Der er givet mulighed for at anvende strukturerede bindinger (structured binding) som betingelse i if- og switch-operatorer.
- Der er tilføjet mulighed for at bruge flere placeholder-variabler med navnet „_“ i samme synlighedsområde, for eksempel er de følgende konstruktioner nu korrekte: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // tidligere viste det en advarsel i -Wunused mode }
- Muligheden for at bruge strengliteral på steder, hvor de ikke bruges til at initialisere karakterarrays og ikke indgår i den resulterende kode, men kun anvendes under kompilering til diagnostiske meddelelser og forbehandling, f.eks. som parametre for direktiver og attributter _Pragma, asm, extern, static_assert, [[deprecated]] og [[nodiscard]].
- Indbyggede funktioner er tilføjet: „__builtin_is_within_lifetime“ til at kontrollere aktiviteten af alternativet i unioner og „__builtin_is_virtual_base_of“ for at kontrollere, om basisklassen er virtuel.
- Trivielle uendelige løkker uden udefineret adfærd er implementeret.
- Der genereres en fejl ved forsøg på at fjerne en pointer til en ufuldstændig type.
- Syntaksen til deklaration af variabelparametre med ellipsis uden forudgående komma (f.eks. når der angives „void e(int…)“ i stedet for „void e(int, …)“) er erklæret forældet.
- Brug af makroer til at erklære moduler er forbudt.
- Det er blevet forældet at udføre implicitte konverteringer af enum-værdier i aritmetiske beregninger. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // forældet int k = f - e; // forældet int x = +f - e; // OK }
- Støtten til direkte sammenligning af arrays er ophørt. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
- Den skabelonklasse is_trivial er erklæret forældet.
Kilde: opennet.ru
