Standard C++26 approvato

Il comitato ISO per la standardizzazione del linguaggio C++ ha completato e approvato la versione finale della specifica, che forma lo standard internazionale "C++26". Le funzionalità presentate nella specifica sono già supportate in parte nei compilatori GCC, Clang e Microsoft Visual C++. Le librerie standard che supportano C++26 sono state implementate nell'ambito del progetto Boost.

Nei prossimi due mesi, la specifica approvata sarà in fase di preparazione del documento per la pubblicazione, durante la quale sarà condotto un lavoro di revisione editoriale per correggere errori ortografici e refusi. All'inizio di novembre, la versione risultante del documento sarà inviata all'ISO per la pubblicazione con il nome formale ISO/IEC 14882:2026.

Caratteristiche principali di C++26:

  • Sono stati implementati elementi di programmazione contrattuale (Contracts), che consentono di definire specifiche formali per le interfacce mediante tre nuovi operatori: pre (precondizione), post (postcondizione) e contract_assert (verifica dell'affermazione). L'operatore "pre" definisce le condizioni preliminari che devono essere soddisfatte prima della chiamata (verifica dei dati in ingresso); "post" — le condizioni che devono essere rispettate dopo l'esecuzione (requisiti per i dati in uscita); contract_assert — condizioni per l'insorgere di eccezioni. Questa funzionalità sarà disponibile in GCC 16. int f(const int x) pre (x != 1) // requisiti per i dati in ingresso post (r : r == x && r != 2) // requisiti per il risultato; r — valore del risultato { contract_assert (x != 3); return x; }
  • Aggiunta la supporto per la riflessione (Reflection), che consente di monitorare e modificare gli elementi del programma durante la fase di compilazione. Sono stati aggiunti nuovi operatori "^^" per ottenere informazioni meta sui costrutti grammaticali e "[:…:]" per eseguire la trasformazione inversa. Per la trasformazione e l'elaborazione delle informazioni ottenute durante l'ispezione è stata proposta la libreria std::meta e sono disponibili funzionalità come i calcoli con le costanti. Il supporto per la riflessione sarà aggiunto in 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’ e ‘j’ hanno valori diversi. static_assert(constant_of(^^i) == constant_of(^^j)); // ‘i’ e ‘j’ sono uguali static_assert(^^i != std::meta::reflect_constant(42)); // diverso dal valore 42
  • È stato aggiunto l'operatore «template for» per l'iterazione su elementi come pacchetti di parametri, oggetti simili a tuple e risultati di riflessione (metaoggetti), durante la fase di compilazione in uno stile di ciclo normale. Durante l'esecuzione del «template for», il corpo del ciclo viene espanso per ogni elemento e ogni iterazione viene elaborata in un'area di visibilità separata, in cui la variabile che cambia nel ciclo è una costante. Nel contesto della riflessione, il «template for» può essere utilizzato per l'iterazione sulle proprietà di classi o enumerazioni. Questa funzionalità sarà disponibile in GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } verrà espanso in: 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); } } }
  • È stato aggiunto il framework std::execution per l'esecuzione asincrona e parallela del codice. Sono forniti oggetti scheduler, che definiscono lo scheduler per l'esecuzione dei lavori (thread, pool di thread, GPU, event loop), sender, che definisce il lavoro eseguito, e receiver — il gestore del risultato. 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();
  • È stata aggiunta la libreria std::simd per parallelizzare l'esecuzione delle operazioni sui dati utilizzando set di istruzioni SIMD, come AVX-512 e NEON, con l'uso del sistema di tipi standard 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;
  • È stata proposta un'implementazione di un vettore (array) di dimensione variabile std::inplace_vector, che viene allocato nello stack, la cui dimensione è definita durante la fase di compilazione. L'API è simile a std::vector, ma gli elementi dell'array non vengono memorizzati nell'heap, ma all'interno dell'oggetto. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
  • È stata aggiunta la direttiva «#embed», destinata a incorporare nel codice risorse binarie. const unsigned char icon_display_data[] = { #embed "art.png" };
  • È stato aggiunto il supporto per la generazione e la gestione delle eccezioni durante la fase di compilazione in caso di errori nel contesto constexpr. constexpr std::optional<unsigned> 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<«([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})»>(input); if (!correct) { throw incorrect_date{input}; } return build_date(year, month, day); }
  • È stata implementata una struttura dati std::hive per l'archiviazione non ordinata dei dati e per garantire il riutilizzo della memoria liberata dopo la rimozione di elementi. La struttura è ottimizzata per carichi con alta intensità di aggiunta e rimozione di elementi in ordine casuale. A differenza degli array, la rimozione di un elemento in std::hive non provoca uno spostamento degli altri elementi, ma segna semplicemente l'elemento rimosso come vuoto, con il successivo riempimento della posizione liberata all'aggiunta di un nuovo elemento.
  • È stata aggiunta la libreria std::linalg con API per l'algebra lineare, basata su BLAS.
  • È stato introdotto il supporto per il meccanismo di sincronizzazione Hazard pointer, che consente di evitare il rilascio della memoria degli oggetti che sono ancora in uso in altri thread, senza l'uso di lock. Quando un oggetto viene rimosso, esso viene solo contrassegnato come rimosso, ma la memoria occupata dall'oggetto viene liberata solo quando tutti i thread abbandonano il puntatore hazard impostato durante l'utilizzo dell'oggetto.
  • È stato aggiunto il supporto per il meccanismo di sincronizzazione RCU (Read-Copy Update) — durante le operazioni di scrittura viene creato un nuovo esemplare dell'oggetto, mentre le operazioni di lettura non vengono bloccate e continuano a lavorare con il vecchio esemplare. Dopo il completamento delle modifiche, il nuovo esemplare diventa attivo e nuove operazioni di lettura vengono effettuate con esso, mentre il vecchio esemplare viene rimosso dopo la conclusione dei thread che lo stanno leggendo.
  • Sono state apportate modifiche per migliorare la sicurezza della libreria standard, come controlli sui valori ammessi e sul superamento dei limiti del buffer. Ad esempio, durante l'accesso all'elemento «constexpr reference operator[](size_type idx) const;» viene aggiunto un controllo sulla condizione «idx < size()".
  • È stata fornita la possibilità di utilizzare la parola chiave «constexpr» con una variante dell'operatore «new» (placement new) per posizionare un oggetto in memoria precedentemente allocata durante la compilazione.
  • È stata aggiunta la supporto per il binding strutturato (structured binding) nel contesto di «constexpr», cioè i riferimenti a espressioni costanti possono ora essere esse stesse espressioni costanti. Il supporto è stato implementato per array e strutture semplici. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
  • Nel binding strutturato è stata aggiunta la possibilità di utilizzare la sintassi «…» per specificare pacchetti (pack) che catturano il numero rimanente di elementi nella sequenza assegnata. auto [x,y,z] = f(); // nelle variabili x, y, z verranno memorizzati tre elementi restituiti da f(). auto […xs] = f(); // nel pacchetto xs verranno memorizzati tutti gli elementi restituiti da f(). auto [x, …rest] = f(); // In x verrà memorizzato il primo elemento, e in rest gli altri. auto [x, y, …rest] = f(); // In x verrà memorizzato il primo elemento, in y il secondo, e in rest il terzo. auto [x, …rest, z] = f(); // in x il primo, in rest il secondo, in z il terzo.
  • È stata aggiunta la supporto per la «movibilità triviale» dei tipi (Trivial Relocatability), che consente di ottimizzare il trasferimento degli oggetti di un certo tipo tramite la loro clonazione in memoria senza invocare costruttori o distruttori. Per le classi sono state implementate le proprietà memberwise_trivially_relocatable e memberwise_replaceable, e per lo spostamento a basso livello di uno o più oggetti sono state aggiunte le funzioni trivially_relocate_at e trivially_relocate.
  • È stato implementato il supporto per allegare la funzione main() al modulo globale e per definire la funzione main() nei moduli nominati.
  • È stato aggiunto l'operatore variabile «friend» («friend Ts…»).
  • Sono stati implementati attributi per il binding strutturato;
  • È stata aggiunta la sintassi ‘= delete(«motivo»)’.
  • Il set di caratteri di base include «@», «$» e «`».
  • È stata fornita la possibilità di applicare il binding strutturato (structured binding) come condizione negli operatori if e switch.
  • È stata aggiunta la possibilità di utilizzare più variabili di riempimento con il nome «_» in un singolo ambito, ad esempio, ora sono costruzioni valide: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // precedentemente mostrava un avviso in modalità -Wunused }
  • È stata fornita la possibilità di utilizzare letterali di stringa in un contesto in cui non vengono utilizzati per inizializzare un array di caratteri e non vengono inclusi nel codice risultante, ma vengono applicati solo durante la compilazione per messaggi diagnostici e pre-processamento, ad esempio, come parametri per direttive e attributi _Pragma, asm, extern, static_assert, [[deprecated]] e [[nodiscard]].
  • Aggiunte funzioni incorporate: «__builtin_is_within_lifetime» per verificare l'attività di una alternativa in unione (union) e «__builtin_is_virtual_base_of» per verificare se una classe base è virtuale.
  • Implementati cicli triviali infiniti senza comportamenti indefiniti.
  • Fornito output di errore alla rimozione di un puntatore a un tipo incompleto.
  • Dichiarata obsoleta la sintassi per la definizione di parametri variabili con tre puntini senza una virgola precedente (ad esempio, quando si specifica «void e(int…)» invece di «void e(int, …)».
  • Vietato l'uso di macro per dichiarare moduli.
  • Dichiarato obsoleto l'esecuzione di conversioni implicite tra valori enumerati in calcoli aritmetici. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // obsoleto int k = f - e; // obsoleto int x = +f - e; // OK }
  • Interrotta la supporto per il confronto diretto di array. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
  • Dichiarato obsoleto la classe template is_trivial.

    Fonte: opennet.ru
Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster