Search code examples
c++standardsdestructortype-traitsc++-concepts

Can T have a destructor when std::is_trivial_v<T> is true?


#include <type_traits>

struct A
{
    ~A() {}
};

int main()
{
    static_assert(std::is_trivial_v<A>); // error   
}

It seems obvious that std::is_trivial_v<A> will be false if A has a destructor.

However, from the cppref page of std::is_trivial, there is nothing requiring A must not have a destructor.

Can T have a destructor when std::is_trivial_v<T> is true?


Solution

  • You need to go further down the rabbit hole. The cppreference page says that trivial types need to be TriviallyCopyable. If you visit that page, it has that it needs a

    Trivial non-deleted destructor

    and if we visit that link we have

    Trivial destructor

    The destructor for class T is trivial if all of the following is true:

    • The destructor is not user-provided (meaning, it is either implicitly declared, or explicitly defined as defaulted on its first declaration)
    • The destructor is not virtual (that is, the base class destructor is not virtual)
    • All direct base classes have trivial destructors
    • All non-static data members of class type (or array of class type) have trivial destructors

    A trivial destructor is a destructor that performs no action. Objects with trivial destructors don't require a delete-expression and may be disposed of by simply deallocating their storage. All data types compatible with the C language (POD types) are trivially destructible.

    So, yes, it needs a trivial destructor and your user provided empty one is not considered trivial.

    The only way you can "write" a destructor and have it be considered trivial is to use

    ~ClassName() = default;