Classes should be final or have a virtual destructor
For sanity. This probably means that structs should be final.
Exception for predicate types, defined as std::true_type, std::false_type, and structs whose specializations all derive from a predicate type with an empty struct-declaration-list. Those structs should be named in snake_case.
Exception for some class hierarchies with no member variables and only static member functions, where no objects of those types are declared. Example: the Serializers, DoubleOrQuantityOrMultivectorSerializer etc.
The ugliness of the above exceptions could be eliminated by giving them, or making them inherit, a deleted destructor; the rule would then be "one of final, virtual destructor, deleted destructor".
Decision.
A class or struct must have one of
- the class-virt-specifier
final; - a virtual destructor (possibly inherited);
- a deleted destructor (possibly inherited). Omit unneeded default destructors (thus default destructors should only appear as virtual in roots of polymorphic type hierarchies).