Standardul C++26 a fost aprobat

Comitetul ISO pentru standardizarea limbajului C++ a finalizat și a aprobat varianta finală a specificației, care formează standardul internațional „C++26”. Funcțiile prezentate în specificație sunt parțial deja suportate în compilatoarele GCC, Clang și Microsoft Visual C++. Bibliotecile standard care susțin C++26 sunt implementate în cadrul proiectului Boost.

În următoarele două luni, specificația aprobată va fi într-o fază de pregătire a documentului pentru publicare, timp în care se va lucra la corectarea erorilor de tipografie și greșelilor ortografice. La începutul lunii noiembrie, varianta rezultantă a documentului va fi trimisă la ISO pentru publicare sub denumirea formală ISO/IEC 14882:2026.

Caracteristicile principale ale C++26:

  • Au fost implementate elemente de programare contractuală (Contracts), care permit definirea specificațiilor formale ale interfețelor prin trei noi operatori: pre (precondiție), post (postcondiție) și contract_assert (verificarea unei afirmații). Operatorul „pre” definește condițiile prealabile care trebuie îndeplinite înainte de apel (verificarea datelor de intrare); „post” — condițiile care trebuie respectate după execuție (cerințe pentru datele de ieșire); contract_assert — condiții pentru apariția excepțiilor. Această posibilitate va apărea în GCC 16. int f(const int x) pre (x != 1) // cerințe pentru datele de intrare post (r : r == x && r != 2) // cerințe pentru rezultat; r — valoarea rezultatului { contract_assert (x != 3); return x; }
  • A fost adăugat suport pentru reflecție (Reflection), care permite monitorizarea și modificarea elementelor programului în timpul compilării. Au fost adăugate noi operatori „^^” pentru obținerea metainformațiilor despre construcția gramaticală și „[:…:]” pentru a efectua inversarea transformării. Pentru a transforma și gestiona informațiile obținute în urma inspectării, a fost propusă biblioteca std::meta, iar posibilitățile disponibile includ calcule cu constante. Suportul pentru reflecție va fi adăugat în 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’ și ‘j’ au valori diferite. static_assert(constant_of(^^i) == constant_of(^^j)); // ‘i’ și ‘j’ sunt identici static_assert(^^i != std::meta::reflect_constant(42)); // diferit de valoarea 42
  • A fost adăugat operatorul „template for” pentru a itera elemente, cum ar fi pachete de parametrii, obiecte asemănătoare tuplelor și rezultate de reflecție (metaobiecte), în faza de compilare, în stilul unui ciclu obișnuit. La execuția „template for”, corpul ciclului este desfășurat pentru fiecare element, iar fiecare iterație este procesată într-un domeniu de vizibilitate separat, în care variabila care se schimbă în ciclu este constantă. În contextul reflecției, „template for” poate fi aplicat pentru a parcurge proprietățile claselor sau enumerărilor. Capacitatea va apărea în GCC 16.void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } }va fi desfășurat în: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); } } }
  • A fost adăugat cadrul std::execution pentru execuția asincronă și paralelă a codului. Se oferă obiecte scheduler, care definesc planificatorul de execuție a muncii (fir, pool de fire, GPU, buclă de evenimente), sender, care definește lucrarea efectuată, și receiver — handlerul de rezultate.using namespace std::execution; calendar 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();
  • A fost adăugată biblioteca std::simd pentru a paraleliza executarea operațiunilor asupra datelor folosind seturi de instrucțiuni SIMD, cum ar fi AVX-512 și NEON, folosind sistemul standard de tipuri 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;
  • A fost propusă o implementare a vectorului (array-ului) de dimensiuni variabile std::inplace_vector, care este plasată în stivă, iar dimensiunea sa este definită în faza de compilare. API-ul este similar cu std::vector, dar elementele array-ului sunt stocate nu în „heap”, ci în interiorul obiectului.inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
  • A fost adăugată directiva „#embed”, destinată încorporării în cod a resurselor binare.const unsigned char icon_display_data[] = { #embed "art.png" };
  • A fost adăugată suportul pentru generarea și gestionarea excepțiilor în timpul compilării în cazul unor erori în contextul 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); }
  • A fost implementată structura de date std::hive pentru stocarea neordonată a datelor și asigurarea reutilizării memoriei eliberate după elementele șterse. Structura este optimizată pentru sarcini cu o intensitate mare de adăugare și ștergere a elementelor în ordine aleatorie. Spre deosebire de array-uri, ștergerea unui element în std::hive nu cauzează o deplasare a altor elemente, ci duce la marcarea elementului șters drept gol, urmând să fie umplută poziția liberă la adăugarea unui nou element.
  • A fost adăugată biblioteca std::linalg cu API pentru algebră liniară, bazată pe BLAS.
  • A fost adăugat suportul pentru mecanismul de sincronizare Hazard pointer, care permite evitarea eliberării memoriei obiectelor cu care se continuă lucrul în alte thread-uri, fără a impune blocări. La ștergerea unui obiect, acesta este marcat ca șters, dar memoria ocupată de obiect este eliberată doar când toate thread-urile au eliminat hazard pointer-ul, stabilit în timpul lucrului cu obiectul.
  • A fost adăugat suportul pentru mecanismul de sincronizare RCU (Read-Copy Update) — în timpul operațiunilor de scriere se creează o nouă instanță a obiectului, iar operațiunile de citire nu sunt blocate, ci continuă să lucreze cu vechea instanță. După finalizarea modificării, noua instanță devine activă, iar noile operațiuni de citire sunt efectuate cu aceasta, vechea instanță fiind ștearsă după ce thread-urile care o citesc s-au terminat.
  • Au fost aduse modificări pentru întărirea securității bibliotecii standard, cum ar fi verificările valorilor valide și a depășirii limitelor buffer-ului. De exemplu, când se accesează elementul „constexpr reference operator[](size_type idx) const;” se adaugă o verificare a condiției „idx < size()".
  • A fost oferită posibilitatea utilizării cuvântului cheie „constexpr” cu o variantă a operatorului „new” (placement new) pentru plasarea unui obiect în memorie prealocată în timpul compilării.
  • Suport pentru legături structurate (structured binding) a fost adăugat în contextul „constexpr”, adică referințele la expresii constante pot fi acum ele însele expresii constante. Suportul este implementat pentru array-uri și structuri simple. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
  • Legăturile structurate au fost îmbogățite cu posibilitatea de a utiliza sintaxa „…” pentru a indica pachete (pack) care captează numărul rămas de elemente din secvența de asignare. auto [x,y,z] = f(); // în variabilele x, y, z vor fi înregistrate cele trei elemente returnate de f(). auto […xs] = f(); // în pachetul xs vor fi înregistrate toate elementele returnate de f(). auto [x, …rest] = f(); // În x va fi înregistrat primul element, iar în rest — celelalte. auto [x, y, …rest] = f(); // În x va fi înregistrat primul element, în y — al doilea, iar în rest — al treilea. auto [x, …rest, z] = f(); // în x — primul, în rest — al doilea, în z — al treilea.
  • A fost adăugat suport pentru „mutabilitatea trivială” a tipurilor (Trivial Relocatability), permițând optimizarea mișcărilor obiectelor unui anumit tip prin clonarea lor în memorie fără a apela constructori sau destructori. Pentru clase au fost implementate proprietățile memberwise_trivially_relocatable și memberwise_replaceable, iar pentru mutarea la un nivel inferior a unuia sau mai multor obiecte au fost adăugate funcțiile trivially_relocate_at și trivially_relocate.
  • A fost implementat suportul pentru asocierea funcției main() cu modulul global și definirea funcției main() în modulele numite.
  • A fost adăugat operatorul variadic „friend” („friend Ts…”).
  • A fost implementat un atribut pentru legături structurate;
  • A fost adăugat sintaxa „= delete(„motiv”)”.
  • Setul de caractere de bază include „@”, „$” și „`”.
  • A fost oferită posibilitatea de a aplica legătura structurată (structured binding) ca condiție în operatorii if și switch.
  • A fost adăugată posibilitatea de a folosi mai multe variabile de umplere cu numele „_” într-un singur domeniu de vizibilitate, de exemplu, acum sunt corecte construcțiile: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // anterior se afișa un avertisment în modul -Wunused }
  • A fost posibilă utilizarea literalelor de tip string în contexte în care nu sunt utilizate pentru inițializarea unui tablou de caractere și nu apar în codul rezultat, ci sunt folosite doar în timpul compilării pentru mesaje de diagnosticare și preprocesare, de exemplu, ca parametri ai directivei și atributelor _Pragma, asm, extern, static_assert, [[deprecated]] și [[nodiscard]].
  • Au fost adăugate funcții încorporate: «__builtin_is_within_lifetime» pentru a verifica activitatea alternativei în uniuni și «__builtin_is_virtual_base_of» pentru a verifica dacă o clasă de bază este virtuală.
  • Au fost implementate bucle triviale infinite fără comportament nedefinit.
  • Este generată o eroare la ștergerea unui pointer către un tip incomplet.
  • A fost declarat ca fiind învechit sintaxa de definire a parametrilor variabili cu trei puncte fără o virgulă anterioară (de exemplu, când se specifică «void e(int…)» în loc de «void e(int, …)».
  • Utilizarea macrocomenzilor pentru a declara module este interzisă.
  • Execuția conversiilor implicite ale valorilor enum în calculele aritmetice a fost declarată învechită. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // învechit int k = f - e; // învechit int x = +f - e; // OK }
  • S-a oprit suportul pentru compararea directă a tablourilor. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
  • A fost declarat ca fiind învechit clasa template is_trivial.

    Sursa: opennet.ro
Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster