Standard C++20 approvato

Comitato ISO per la standardizzazione del linguaggio C++ ha approvato standard internazionale “C++20“. Le funzionalità presentate nella specifica, ad eccezione di rarissimi casi, supportano nei compilatori GCC, Clang e Microsoft Visual C++. Le librerie standard che supportano C++20 sono implementate nel progetto Boost.

Nei prossimi due mesi, la specifica approvata sarà in fase di preparazione del documento per la pubblicazione, nella quale saranno effettuate correzioni editoriali di errori ortografici e refusi. All'inizio di novembre, la versione finale del documento sarà inviata all'ISO per la pubblicazione con il nome formale ISO/IEC 14882:2020. Nel frattempo, il comitato ha già iniziato a lavorare sul prossimo standard C++23 (C++2b) e nella prossima riunione virtuale discuterà possibili novità.

Principali caratteristiche C++20 (esempi di codice):

  • Aggiunte «concetti», estensioni dei template che permettono di definire un insieme di requisiti per i parametri del template, che durante la compilazione limitano il set di argomenti che possono essere passati come parametri del template. I concetti possono essere utilizzati per evitare incongruenze logiche tra le proprietà dei tipi di dati utilizzati all'interno del template e le proprietà dei tipi di dati dei parametri di ingresso.

    template<typename T>
    concept EqualityComparable = requires(T a, T b) {
    { a == b } -> std::boolean;
    { a != b } -> std::boolean;
    };

  • Includo estensione per lavorare con i moduli, che possono essere utilizzati al posto dei file di intestazione. I moduli offrono un nuovo modo di organizzare i testi sorgente basato sulla definizione dei confini dei componenti, senza i file di intestazione collegati tramite «#include».
  • Macro __VA_OPT__ per l'espansione adattiva di macro variabili in base alla presenza di token nell'argomento variabile.
  • Supporto per l'operatore «» per il confronto a tre vie.
  • Supporto per inizializzatori di elementi per default per i campi bit.
  • Possibilità di catturare espressioni «*this» nelle lambda.

    struct int_value {
    int n = 0;
    auto getter_fn() {
    // BAD:
    // return [=]() { return n; };

    // GOOD:
    return [=, *this]() { return n; };
    }
    };

  • Richiamo di elementi tramite puntatore (Pointer-to-member), utilizzando puntatori a oggetti temporanei definiti tramite l'espressione «const &».
  • Operatore delete con distruttore, descritto nel documento P0722R1.
  • Le classi sono autorizzate a utilizzare parametri di template senza tipo.

    struct foo {
    foo() = default;
    constexpr foo(int) {}
    };

    template
    auto get_foo() {
    return f;
    }

    get_foo(); // utilizza il costruttore implicito
    get_foo();

  • Espressioni lambda non memorizzate con costruttore.
  • Riconoscibilità della sintassi dei template per le espressioni lambda («auto f = [](std::vector v)»).
  • Possibilità di utilizzare letterali di stringa come parametri di template.
  • Supporto della sintassi di inizializzazione in stile C — i campi non esplicitamente elencati nell'elenco di inizializzazione vengono inizializzati per default.

    struct A {
    int x;
    int y;
    int z = 123;
    };

    A a {.x = 1, .z = 2}; // a.x == 1, a.y == 0, a.z == 2

  • Supporto per membri vuoti delle strutture dati.
  • Supporto per gli attributi likely e unlikely per informare l'ottimizzatore sulla probabilità di attivazione della struttura condizionale («[[likely]] if (random > 0) {«).
  • Possibilità di utilizzare intervalli per inizializzare i valori di una variabile nel ciclo «for»

    for (auto v = std::vector{1, 2, 3}; auto& e : v) {

  • Calcolo automatico della dimensione dell'array in new («new double[]{1,2,3}»);
  • L'attributo «[[no_unique_address]]» che fa sì che le variabili senza dati non occupino spazio.
  • Puntatori atomici (std::atomic<shared_ptr> e std::atomic<weak_ptr>).
  • Possibilità di chiamare funzioni virtuali in espressioni condizionali.
  • Supporto per funzioni rapide (immediate) che possono lavorare solo con costanti.

    consteval int sqr(int n) {
    return n * n;
    }

    constexpr int r = sqr(100); // OK
    int x = 100;
    int r2 = sqr(x); // ERRORE: ‘x’ non può essere utilizzato come costante

  • Possibilità di applicare constexpr con funzioni virtuali («constexpr virtual int f() const { return 2; }»).
  • Nella libreria standard:
    • Aggiunto il supporto per il tipo char8_t per le stringhe UTF-8.
    • Aggiunti i file di intestazione bit (operazioni bitwise) e version.
    • È stata introdotta la possibilità di controllare i prefissi e suffissi delle stringhe (starts_with, ends_with).
    • Aggiunti i type traits std::remove_cvref, std::unwrap_reference, std::unwrap_decay_ref, std::is_nothrow_convertible e std::type_identity.
    • Aggiunte le funzioni std::midpoint, std::lerp, std::bind_front, std::source_location, std::visit, std::is_constant_evaluated e std::assume_aligned.
    • In std::make_shared è stato aggiunto il supporto per gli array.
    • Aggiunta la funzione std::to_array per convertire oggetti simili a array in std::array.
  • Sintassi delle enumerazioni più conveniente:

    enum class rgba_color_channel { rosso, verde, blu, alfa };

    std::string_view to_string(rgba_color_channel my_channel) {
    switch (my_channel) {
    using enum rgba_color_channel;
    case rosso: return «rosso»;
    case verde: return «verde»;
    case blu: return «blu»;
    case alfa: return «alfa»;
    }
    }

  • L'uso dell'operazione «,» («a[b,c]») è vietato negli indici a causa di comportamenti indefiniti. È stata interrotta la supporto per la maggior parte delle operazioni con variabili dichiarate con la parola chiave volatile, incluse le operazioni «++» e «—» con i tipi standard.
  • Ridotto il numero di situazioni in cui è necessario specificare «typename» per informare della presenza di un tipo.

Fonte: opennet.ru

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster