For a class to be a literal type, all you need is a constexpr
destructor. = delete
d functions have been allowed to be constexpr
for a long time.
However, if you don’t mark it constexpr
, then it isn’t constexpr
except defaulted destructors which have an extra rule ([class.dtor]p9):
A defaulted destructor is a constexpr destructor if it satisfies the requirements for a constexpr destructor ([dcl.constexpr]).
Which a class with no members does, so ~a() = default;
is constexpr.
~c() = delete;
isn’t constexpr because there’s no reason for it to be.
constexpr ~f() = delete;
is constexpr because it’s marked constexpr
.
Clang is correct here: ~s() = delete;
would not be constexpr
if it is not specified to be, so can’t be used as a literal type. It seems that std::is_literal_v<c>
passes in gcc erroneously.