So I've been messing around trying to implement a variant/tagged union class and needed a way to write generic destructors and made what I thought was a silly mistake forgetting that some types don't have destructors, doing something like
template<typename T>
void destruct(T& thing) {
thing.~T();
}
Yet, this worked fine even with types that didn't have destructors, like int or struct A {int b;};. I still think it's more readable and easier to reason with something that uses something like this
template<typename T>
void destruct(T& thing) {
if constexpr(std::is_destructible<T>::value) {
thing.~T();
}
}
But is there actually any difference between the code? The first one feels pretty undefined behavoiry/just wrong to me.