Asserzioni statiche



Categoria Macro static_assert( … ) Garanzia Quando / Perché verificarla con un’asserzione Scenario tipico di fallimento
Ciclo di vita / distruzione std::is_nothrow_destructible_v<T> Il distruttore è dichiarato noexcept → non può lanciare eccezioni. Gli oggetti possono essere distrutti durante lo srotolamento dello stack o su thread di lavoro; un distruttore che lancia eccezioni causerebbe una chiamata a std::terminate. Qualcuno aggiunge ~T() { if(err) throw; } o un membro il cui distruttore può lanciare eccezioni.
  std::is_trivially_destructible_v<T> Il compilatore non fa nulla nel distruttore (distruzione bit a bit). Necessario solo per codice POD / lock-free di bassissimo livello (ad es. per memorizzare oggetti in std::atomic<T>). Aggiunta di un std::vector, di uno smart pointer o di un distruttore scritto dall’utente.
Spostamento std::is_nothrow_move_constructible_v<T> Spostare un T non può lanciare eccezioni. Garantisce che i contenitori (std::vector, std::optional) mantengano la garanzia forte di sicurezza rispetto alle eccezioni ed evitino copie. Rimozione di noexcept dal costruttore di spostamento o aggiunta di un membro la cui operazione di spostamento può lanciare eccezioni.
  std::is_nothrow_move_assignable_v<T> L’assegnazione per spostamento è noexcept. Stesse ragioni di cui sopra; velocizza inoltre gli algoritmi che si affidano a uno swap veloce. Come nella colonna precedente.
Protezione dalla copia !std::is_copy_constructible_v<T> La costruzione per copia è eliminata. Oggetti grandi / unici non devono mai essere copiati accidentalmente (ad es. le tabelle di traduzione). Un contributore rimuove = delete, abilitando accidentalmente copie costose.
  !std::is_copy_assignable_v<T> L’assegnazione per copia è eliminata. Come sopra. Idem.
Costo della copia / natura POD std::is_trivially_copyable_v<T> L’oggetto può essere spostato direttamente con memcpy (senza operazioni di copia / spostamento o distruttori personalizzati). Tipi valore molto piccoli passati per valore ad alta frequenza, dati in code lock-free. Aggiunta di uno smart pointer o di operazioni di copia / spostamento o distruttori scritti dall’utente.
Scambiabilità (C++17) std::is_nothrow_swappable_v<T> swap(a,b) è noexcept e ha un costo ridotto. Consente agli algoritmi STL di usare percorsi di esecuzione con scambi veloci (ad es. all’interno di std::sort, std::map::insert). Un swap() personalizzato perde noexcept, oppure le operazioni di spostamento iniziano a lanciare eccezioni.


Come applicarne una

#include <type_traits>
#include <utility>          // for std::is_nothrow_swappable_v

static_assert(std::is_nothrow_move_constructible_v<GTranslationTable>,
              "GTranslationTable move-ctor must be noexcept for vector reallocation!");

static_assert(!std::is_copy_constructible_v<GTranslationTable>,
              "Copying a translation table is disallowed — use move or shared_ptr.");


Scegliere l’asserzione corretta

Intento Trait suggeriti
Tipo valore critico per le prestazioni std::is_trivially_copyable_v<T>
Oggetto che gestisce risorse e viene solo spostato Eliminare le operazioni di copia + verificare con asserzioni i due trait di spostamento senza eccezioni
Oggetto condiviso tra thread Almeno std::is_nothrow_destructible_v<T>
swap personalizzato / uso in mappe ordinate Aggiungere std::is_nothrow_swappable_v<T>