Der Standard C++26 wurde genehmigt.

Das ISO-Ausschuss für die Standardisierung der Programmiersprache C++ hat die endgültige Version der Spezifikation genehmigt, die den internationalen Standard „C++26“ bildet. Die in der Spezifikation vorgestellten Funktionen werden teilweise bereits in den Compilern GCC, Clang und Microsoft Visual C++ unterstützt. Die unterstützenden Standardbibliotheken für C++26 wurden im Rahmen des Boost-Projekts implementiert.

In den nächsten zwei Monaten wird die genehmigte Spezifikation in der Phase der Dokumentenvorbereitung zur Veröffentlichung sein, in der redaktionelle Arbeiten zur Korrektur von Rechtschreibfehlern und Tippfehlern durchgeführt werden. Anfang November wird die endgültige Version des Dokuments an ISO zur Veröffentlichung unter dem formalen Namen ISO/IEC 14882:2026 gesendet.

Hauptmerkmale von C++26:

  • Elemente der Vertragsprogrammierung (Contracts) wurden implementiert, die es ermöglichen, formale Spezifikationen für Schnittstellen mit drei neuen Operatoren zu definieren: pre (Präbedingung), post (Nachbedingung) und contract_assert (Assertionsprüfung). Der Operator „pre“ definiert die Vorbedingungen, die vor dem Aufruf erfüllt sein müssen (Eingabedaten überprüfen); „post“ – die Bedingungen, die nach der Ausführung eingehalten werden müssen (Ausgabedatenanforderungen); contract_assert – Bedingungen für das Auftreten von Ausnahmen. Diese Möglichkeit wird in GCC 16 verfügbar sein. int f(const int x) pre (x != 1) // Anforderungen an die Eingabedaten post (r : r == x && r != 2) // Anforderungen an das Ergebnis; r – der Ergebniswert { contract_assert (x != 3); return x; }
  • Unterstützung für Reflexion (Reflection) wurde hinzugefügt, die es ermöglicht, Elemente des Programms in der Kompilierungsphase zu verfolgen und zu modifizieren. Es wurden neue Operatoren „^^“ zur Erfassung von Metainformationen über grammatikalische Konstrukte und „[:…:]“ zur Durchführung von Rücktransformierungen hinzugefügt. Für die Transformation und Verarbeitung der während der Inspektion erhaltenen Informationen wird die Bibliothek std::meta vorgeschlagen, und es stehen Funktionen wie Berechnungen mit Konstanten zur Verfügung. Reflexionsunterstützung wird in GCC 16 hinzugefügt. 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' und 'j' haben unterschiedliche Werte. static_assert(constant_of(^^i) == constant_of(^^j)); // 'i' und 'j' sind identisch static_assert(^^i != std::meta::reflect_constant(42)); // unterscheidet sich von dem Wert 42
  • Ein Operator „template for“ wurde hinzugefügt, um Elemente wie Parameterpakete, tuple-ähnliche Objekte und Reflexionsergebnisse (Meta-Objekte) während der Kompilierung im Stil einer regulären Schleife zu iterieren. Bei der Ausführung von „template for“ wird der Schleifeninhalt für jedes Element entfaltet, und jede Iteration wird in einem separaten Geltungsbereich verarbeitet, in dem die sich im Schleifenverlauf ändernde Variable eine Konstante ist. Im Kontext der Reflexion kann „template for“ verwendet werden, um die Eigenschaften von Klassen oder Enumerationen zu durchlaufen. Diese Funktion wird in GCC 16 verfügbar sein. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } wird entfaltet zu: 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); } } }
  • Das Framework std::execution für die asynchrone und parallele Ausführung von Code wurde hinzugefügt. Es werden Objekte scheduler bereitgestellt, die den Arbeitsausführungsplaner (Thread, Threadpool, GPU, Event-Loop) definieren, sender, die die auszuführende Arbeit definieren, und receiver, den Ergebnisverarbeiter. 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();
  • Die Bibliothek std::simd wurde hinzugefügt, um die Ausführung von Datenoperationen mithilfe von SIMD-Befehlssätzen wie AVX-512 und NEON zu parallelisieren, unter Verwendung des standardmäßigen Typsystems von 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;
  • Eine Implementierung des Vektors (Arrays) variabler Größe std::inplace_vector wurde vorgeschlagen, der auf dem Stack platziert wird, wobei die Größe zur Kompilierungszeit festgelegt wird. Die API ähnelt der von std::vector, aber die Array-Elemente werden nicht im „Heap“, sondern innerhalb des Objekts gespeichert. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
  • Die Direktive „#embed“ wurde hinzugefügt, die dazu dient, binäre Ressourcen in den Code einzubetten. const unsigned char icon_display_data[] = { #embed "art.png" };
  • Unterstützung für die Generierung und Verarbeitung von Ausnahmen während der Kompilierung bei Fehlern im Kontext von constexpr hinzugefügt. 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); }
  • Die Datenstruktur std::hive wurde implementiert, um Daten ungeordnet zu speichern und die Wiederverwendung von Speicher zu ermöglichen, der nach dem Löschen von Elementen frei geworden ist. Die Struktur ist für hohe Hinzufügungs- und Löschintensitäten bei beliebiger Reihenfolge optimiert. Im Gegensatz zu Arrays bewirkt das Löschen eines Elements in std::hive keinen Verschub anderer Elemente, sondern führt lediglich dazu, dass das gelöschte Element als leer markiert wird, wobei der freigewordene Platz bei der Hinzufügung eines neuen Elements wieder gefüllt wird.
  • Die Bibliothek std::linalg wurde mit einer API für lineare Algebra, basierend auf BLAS, hinzugefügt.
  • Unterstützung für den Hazard-Pointer-Synchronisationsmechanismus hinzugefügt, der es ermöglicht, ohne Sperren zu verhindern, dass der Speicher für Objekte freigegeben wird, mit denen in anderen Threads weiterhin gearbeitet wird. Bei der Löschung eines Objekts wird es lediglich als gelöscht markiert, aber der vom Objekt belegte Speicher wird erst freigegeben, wenn alle Threads den während der Arbeit mit dem Objekt gesetzten Hazard-Pointer entfernt haben.
  • Unterstützung für den RCU (Read-Copy Update)-Synchronisationsmechanismus hinzugefügt – bei Schreibvorgängen wird eine neue Instanz des Objekts erstellt, während Lesevorgänge nicht blockiert werden und weiter mit der alten Instanz arbeiten. Nach Abschluss der Änderungen wird die neue Instanz aktiv, und neue Leseoperationen werden bereits mit ihr durchgeführt, während die alte Instanz nach dem Abschluss aller sie lesenden Threads gelöscht wird.
  • Änderungen zur Verbesserung der Sicherheit der Standardbibliothek vorgenommen, wie z. B. Überprüfungen auf gültige Werte und Pufferüberschreitungen. Beispielsweise wird bei dem Zugriff auf das Element "constexpr reference operator[](size_type idx) const;" eine Prüfung hinzugefügt, ob "idx < size()".
  • Die Möglichkeit, das Schlüsselwort "constexpr" mit einer Variante des Operators "new" (Placement new) zu verwenden, um ein Objekt während der Kompilierung im Voraus zugewiesenen Speicher zu platzieren, wurde bereitgestellt.
  • Unterstützung für strukturierte Bindungen (structured binding) im Kontext von „constexpr“ hinzugefügt, d.h. Referenzen auf konstante Ausdrücke können jetzt selbst konstante Ausdrücke sein. Die Unterstützung wurde für Arrays und einfache Strukturen implementiert. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
  • Die strukturierten Bindungen wurden um die Möglichkeit erweitert, die Syntax „...“ zur Angabe von Paketen (pack), die die verbleibende Anzahl von Elementen aus der zuweisbaren Sequenz erfassen, zu verwenden. auto [x,y,z] = f(); // in die Variablen x, y, z werden drei Elemente geschrieben, die von f() zurückgegeben werden. auto […xs] = f(); // im Paket xs werden alle Elemente gespeichert, die von f() zurückgegeben werden. auto [x, …rest] = f(); // In x wird das erste Element gespeichert, während in rest die übrigen gespeichert werden. auto [x, y, …rest] = f(); // In x wird das erste Element gespeichert, in y das zweite und in rest das dritte. auto [x, …rest, z] = f(); // in x – das erste, in rest – das zweite, in z – das dritte.
  • Unterstützung für die „triviale Beweglichkeit“ von Typen (Trivial Relocatability) hinzugefügt, die es ermöglicht, Bewegungen von Objekten eines bestimmten Typs durch deren Klonierung im Speicher ohne Aufruf von Konstruktoren oder Destruktoren zu optimieren. Für Klassen wurden die Eigenschaften memberwise_trivially_relocatable und memberwise_replaceable implementiert, und für die niedrige Stufe der Bewegung eines oder mehrerer Objekte wurden die Funktionen trivially_relocate_at und trivially_relocate hinzugefügt.
  • Unterstützung für das Anheften der Funktion main() an ein globales Modul und die Definition der Funktion main() in benannten Modulen implementiert.
  • Variadischer Operator „friend“ („friend Ts…“) hinzugefügt.
  • Attribute für strukturierte Bindungen implementiert;
  • Syntax ‚= delete(„Grund“)‘ hinzugefügt.
  • Zum Grundzeichensatz wurden „@“, „$“ und „`“ hinzugefügt.
  • Möglichkeit zur Anwendung strukturierter Bindung (structured binding) als Bedingung in den Operatoren if und switch bereitgestellt.
  • Die Möglichkeit zur Verwendung mehrerer Platzhalter-Variablen mit dem Namen „_“ in einem Sichtbarkeitsbereich hinzugefügt, beispielsweise sind jetzt folgende Konstruktionen korrekt: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // vorher wurde eine Warnung im Modus -Wunused ausgegeben }
  • Die Möglichkeit zur Verwendung von String-Literalen in einem Kontext wurde bereitgestellt, in dem sie nicht zur Initialisierung von Zeichenarrays verwendet werden und nicht in den resultierenden Code gelangen, sondern nur zur Compile-Zeit für Diagnosemeldungen und Preprocessing angewendet werden, beispielsweise als Parameter für Direktiven und Attribute wie _Pragma, asm, extern, static_assert, [[deprecated]] und [[nodiscard]].
  • Es wurden neue eingebaute Funktionen hinzugefügt: „__builtin_is_within_lifetime“ zur Überprüfung der Aktivität eines Alternativwertes in unions und „__builtin_is_virtual_base_of“ zur Überprüfung, ob eine Basisklasse virtuell ist.
  • Triviale unendliche Schleifen ohne undefiniertes Verhalten wurden implementiert.
  • Es wird ein Fehler ausgegeben, wenn ein Zeiger auf einen unvollständigen Typ gelöscht wird.
  • Die Syntax zur Definition variadischer Parameter mit Ellipsen ohne vorhergehendes Komma wurde als veraltet erklärt (z.B. wenn „void e(int…)“ anstelle von „void e(int, …)“ angegeben wird).
  • Die Verwendung von Makros zur Deklaration von Modulen ist verboten.
  • Die implizite Umwandlung von enumerierten Werten in arithmetischen Berechnungen wurde als veraltet angesehen. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // veraltet int k = f - e; // veraltet int x = +f - e; // OK }
  • Die Unterstützung für den direkten Vergleich von Arrays wurde eingestellt. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
  • Die Vorlage der Klasse is_trivial wurde als veraltet erklärt.

    Quelle: opennet.ru
Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server 🔥 Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster