From my experience at developing Qt itself (and Qt-based applications), here's a suggestion for a family of checks. We need to establish a definition for a "value class". In Qt: any class with a public copy constructor. Move-only classes can also be considered value classes but they're very rare in Qt. The value classes that are interesting for us are either thin abstractions (QRect, QPoint) or thick abstractions (QString, QFont). The main feat thick abstractions in Qt are pimpled; thin abstractions have multiple non-pointer data members right into the class itself. (RAII classes, another category of value classes, usually have pointer/references data members. For more info, cf's Marc Mutz' talk at MeetingC++. Runtime polymorphic classes shouldn't be copiable in the first place, so they're not value classes for us.) So, somehow, a thick abstraction is detectable due to the presence of just one data member of type QSharedDataPointer / QExplictlySharedDataPointer etc. If this proves to be hard, we can always have an attribute. For any value class which is public API (not sure how to enforce that; file name in which the declaratino appears?), check that: * QVariant::fromValue(obj); compiles (implying either builtin support in QVariant and/or Q_DECLARE_METATYPE exists) * Q_DECLARE_TYPEINFO / QTypeInfo specialization exists for it. Thin classes are usually primitive, and thick classes are usually movable. * qDebug() << obj; compiles * QDataStream ds; ds << obj; compiles * qHash(obj); compiles (and possibly is noexcept) * The class has a noexcept member swap * A noexcept swap(obj1, obj2) overload in the class' namespace exists * std::hash<Class>{}(obj) compiles (and possibly is noexcept) * The class is final For thin abstractions also check that: * The class itself is NOT exported; only individual, outofline members are * The class follows the rule of 0 * Constructors are noexcept and constexpr * Destruction is trivial (= the class is a literal type) * Any function defined inline is also constexpr; * Any function defined inline is also noexcept -- this may give false positives. In general it's impossible to check due to Lakos' rule; I'd warn nonetheless and have users annotate with noexcept(false). For thick abstractions also check that: * The class is exported * The class follows the rule of 5 (at the moment Qt cannot implement move constructors, though; a resolution is coming)