ISO-kommittén för standardisering av C++-sprÄket har godkÀnt den slutliga versionen av specifikationen som utgör den internationella standarden "C++26". De funktioner som presenteras i specifikationen stöds delvis redan av kompilatorerna GCC, Clang och Microsoft Visual C++. Standardbiblioteken som stöder C++26 har implementerats inom ramen för Boost-projektet.
Under de kommande tvÄ mÄnaderna kommer den godkÀnda specifikationen att vara i beredning för publicering, dÀr arbete kommer att utföras för att redigera stavfel och tryckfel. I början av november kommer den slutgiltiga versionen av dokumentet att skickas till ISO för publicering under det formella namnet ISO/IEC 14882:2026.
Huvudfunktionerna i C++26:
- Element för kontraktsprogrammering (Contracts) har implementerats, vilket gör det möjligt att definiera formella specifikationer för grĂ€nssnitt med tre nya operatörer: pre (före), post (efter) och contract_assert (kontroll av pĂ„stĂ„ende). Operatören "pre" definierar förutsĂ€ttningar som mĂ„ste uppfyllas före anrop (kontroll av ingĂ„ngsvĂ€rden); "post" â villkor som mĂ„ste efterlevas efter utförandet (krav pĂ„ utdata); contract_assert â villkor för undantag. Denna funktionalitet kommer att finnas i GCC 16. int f(const int x) pre (x != 1) // krav pĂ„ ingĂ„ngsvĂ€rden post (r : r == x && r != 2) // krav pĂ„ resultat; r â resultatvĂ€rdet { contract_assert (x != 3); return x; }
- Stöd för reflektion (Reflection) har lagts till, vilket gör det möjligt att spĂ„ra och modifiera programkomponenter under kompilering. Nya operatörer "^^" har lagts till för att fĂ„ meta-information om grammatiska konstruktioner och "[:âŠ:]" för att utföra omvandlingar. För att omvandla och behandla informationen som erhĂ„llits genom inspektion har biblioteket std::meta föreslagits och funktioner som konstantberĂ€kningar Ă€r tillgĂ€ngliga. Stöd för reflektion kommer att lĂ€ggas till 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â och âjâ har olika vĂ€rden. static_assert(constant_of(^^i) == constant_of(^^j)); // âiâ och âjâ Ă€r identiska static_assert(^^i != std::meta::reflect_constant(42)); // skiljer sig frĂ„n vĂ€rdet 42
- En operator "template for" har lagts till för att iterera över element som paket av parametrar, tuples-liknande objekt och reflektionsresultat (metaobjekt) under kompilering i stil med en vanlig loop. Vid körning av "template for" utvecklas loopens kropp för varje element och varje iteration behandlas i ett eget synfÀlt dÀr den förÀnderliga variabeln i loopen Àr en konstant. I reflektionssammanhang kan "template for" anvÀndas för att iterera över egenskaper hos klasser eller enumerationer. Möjligheten kommer att finnas i GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } kommer att utvecklas till: 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); } } }
- Ett ramverk std::execution har lagts till för asynkront och parallellt utförande av kod. Objekt som scheduler tillhandahÄlls, vilket definierar schemalÀggaren för att utföra arbete (trÄd, trÄdpool, GPU, hÀndelseloop), sender som definierar det utförda arbetet, och receiver - resultatbehandlaren. 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 har lagts till för att parallellisera utförandet av operationer pÄ data med hjÀlp av SIMD-instruktionsuppsÀttningar som AVX-512 och NEON, med den standardiserade typ systemet 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;
- En implementation av en vektor (array) av variabel storlek std::inplace_vector, som placeras pÄ stacken, har föreslagits och storleken bestÀms vid kompilering. API:n ligger nÀra std::vector, men elementen i arrayen lagras inte i "heap", utan inuti objektet. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
- Direktivet "#embed" har lagts till för att integrera binÀra resurser i koden. const unsigned char icon_display_data[] = { #embed "art.png" };
- Stöd för generering och hantering av undantag under kompilering vid fel i kontexten constexpr har lagts till. 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); }
- Datakonstruktionen std::hive för oordnad lagring av data och ÄteranvÀndning av minne frigjort efter borttagna element har implementerats. Konstruktionen Àr optimerad för belastningar med hög intensitet av tillÀgg och borttagning av element i godtycklig ordning. Till skillnad frÄn arrayer, orsakar borttagning av ett element i std::hive ingen förskjutning av andra element, utan det borttagna elementet markeras som tomt, och den frigjorda positionen fylls vid tillÀgg av ett nytt element.
- Biblioteket std::linalg med API för linjÀr algebra som baseras pÄ BLAS har lagts till.
- Stöd för synkroniseringsmekanismen Hazard pointer har lagts till, vilket gör det möjligt att förhindra frigöring av minnet för objekt som fortfarande anvÀnds i andra trÄdar utan att sÀtta upp lÄs. Vid borttagning av ett objekt markeras det endast som borttaget, men det minne som objektet anvÀnder frigörs först nÀr alla trÄdar har lyft hazard-pekarna som sÀtts under arbetet med objektet.
- Stöd för synkroniseringsmekanismen RCU (Read-Copy Update) har lagts till â vid skrivoperationer skapas en ny instans av objektet, medan lĂ€soperationer inte blockeras utan fortsĂ€tter att arbeta med den gamla instansen. Efter att Ă€ndringen har slutförts blir den nya instansen aktiv och nya lĂ€soperationer utförs med den, medan den gamla instansen tas bort efter att alla lĂ€sande trĂ„dar har slutfört.
- Ăndringar har gjorts för att stĂ€rka sĂ€kerheten i standardbiblioteket, sĂ„som kontroller av giltiga vĂ€rden och övertrĂ€delse av grĂ€nser för bufferten. Till exempel, vid Ă„tkomst till elementet «constexpr reference operator[](size_type idx) const;» lĂ€ggs en kontroll in av villkoret «idx < size()».
- Möjlighet att anvÀnda nyckelordet «constexpr» med en variant av operatorn «new» (placement new) för att placera ett objekt i förutbestÀmd minne under kompilering har tillhandahÄllits.
- Stöd för strukturerade bindningar (structured binding) har lagts till i kontexten "constexpr", vilket innebÀr att referenser till konstanter nu sjÀlva kan vara konstanter. Stöd har implementerats för arrayer och enkla strukturer. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
- I de strukturerade bindningarna har möjligheten att anvĂ€nda syntaxen "âŠ" lagts till för att ange paket (pack) som fĂ„ngar det Ă„terstĂ„ende antalet element frĂ„n den tilldelade sekvensen. auto [x,y,z] = f(); // tre element returnerade av f() kommer att skrivas till variablerna x, y, z. auto [âŠxs] = f(); // alla element returnerade av f() kommer att skrivas till paketet xs. auto [x, âŠrest] = f(); // x kommer att fĂ„ det första elementet och rest de Ă„terstĂ„ende. auto [x, y, âŠrest] = f(); // x kommer att fĂ„ det första elementet, y det andra och rest det tredje. auto [x, âŠrest, z] = f(); // x fĂ„r det första, rest det andra och z det tredje.
- Stöd för "trivially relocatable" typer (Trivial Relocatability) har lagts till, vilket möjliggör optimering av flyttningar av objekt av en viss typ genom att klona dem i minnet utan att kalla pÄ konstruktorer eller destruktorer. För klasser har egenskaperna memberwise_trivially_relocatable och memberwise_replaceable implementerats, och för lÄgnivÄflyttning av ett eller flera objekt har funktionerna trivially_relocate_at och trivially_relocate lagts till.
- Stöd för att koppla funktionen main() till det globala modulen och definiera funktionen main() i namngivna moduler har implementerats.
- Den variabla operatören "friend" ("friend TsâŠ") har lagts till.
- Attribut för strukturerade bindningar har implementerats.
- Syntaxen â= delete(«orsak»)â har lagts till.
- Tecken som "@", "$" och "`" har lagts till i grunduppsÀttningen av tecken.
- Möjligheten att anvÀnda strukturerad bindning (structured binding) som villkor i if- och switch-operatorer har tillhandahÄllits.
- Möjligheten att anvĂ€nda flera variabler med namnet â_â i en och samma domĂ€n har lagts till, exempelvis Ă€r följande konstruktioner nu giltiga: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // tidigare visades en varning i lĂ€ge -Wunused }
- Möjligheten att anvÀnda strÀngliteraler i kontexter dÀr de inte anvÀnds för att initiera teckenarrayer och inte ingÄr i den resulterande koden, utan endast anvÀnds vid kompilering för diagnostiska meddelanden och preprocessning, exempelvis som parametrar för direktiv och attribut _Pragma, asm, extern, static_assert, [[deprecated]] och [[nodiscard]].
- Inbyggda funktioner har lagts till: «__builtin_is_within_lifetime» för att kontrollera aktiviteten hos alternativ i unioner och «__builtin_is_virtual_base_of» för att kontrollera om basklassen Àr virtuell.
- Triviala oÀndliga loopar har implementerats utan obestÀmd beteende.
- Ett felmeddelande ges vid borttagning av pekaren till en ofullstÀndig typ.
- Syntaxen för att definiera variabla parametrar med tre prickar utan föregĂ„ende kommatecken har förklarats som förĂ„ldrad (till exempel nĂ€r det anges «void e(intâŠ)» istĂ€llet för «void e(int, âŠ)»).
- AnvÀndning av makron för att deklarera moduler Àr förbjudet.
- Implicit omvandling av upprÀknade vÀrden till aritmetiska berÀkningar har klassificerats som förÄldrad. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // förÄldrat int k = f - e; // förÄldrat int x = +f - e; // OK }
- Stödet för direkt jÀmförelse av arrayer har upphört. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
- Den mallklass is_trivial har förklarats som förÄldrad.
KĂ€lla: opennet.ru
