#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?
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;