| Lifetime / destruction |
std::is_nothrow_destructible_v<T> |
Destructor is declared noexcept → can’t throw. |
Objects may be destroyed during stack-unwinding or on worker threads; a throwing dtor would call std::terminate. |
Someone adds ~T() { if(err) throw; } or a member whose destructor can throw. |
| |
std::is_trivially_destructible_v<T> |
Compiler does nothing in the destructor (bit-wise destroy). |
Needed only for ultra-low-level POD / lock-free code (e.g. store in std::atomic<T>). |
Adding a std::vector, smart pointer, or user-written destructor. |
| Movement |
std::is_nothrow_move_constructible_v<T> |
Moving a T cannot throw. |
Ensures containers (std::vector, std::optional) keep strong exception-safety & avoid copies. |
Removing noexcept from the move-ctor or adding a member with a throwing move. |
| |
std::is_nothrow_move_assignable_v<T> |
Move-assignment is noexcept. |
Same reasons as above; also speeds up algorithms that rely on fast swap. |
Same as previous column. |
| Copy-protection |
!std::is_copy_constructible_v<T> |
Copy-construction is deleted. |
Large / unique objects must never be copied accidentally (e.g. translation tables). |
A contributor removes = delete, accidentally enabling expensive copies. |
| |
!std::is_copy_assignable_v<T> |
Copy-assignment is deleted. |
Same as above. |
Ditto. |
| Copy cost / POD-ness |
std::is_trivially_copyable_v<T> |
Object can be moved with raw memcpy (no custom copy / move / dtor). |
Tiny value types passed by value at high frequency, data in lock-free queues. |
Adding a smart pointer or user copy / move / dtor. |
| Swappability (C++17) |
std::is_nothrow_swappable_v<T> |
swap(a,b) is noexcept and cheap. |
Lets STL algorithms use fast swap paths (e.g. inside std::sort, std::map::insert). |
Custom swap() loses noexcept, or move operations start throwing. |