You can make an is_complete type trait, using the fact that it is ill-formed to evaluate sizeof(T) for an incomplete type T:
template
struct is_complete_helper {
template
static auto test(U*) -> std::integral_constant;
static auto test(...) -> std::false_type;
using type = decltype(test((T*)0));
};
template
struct is_complete : is_complete_helper::type {};
and use it to check for is_defined_hash_type by determining if hash is complete. (Live at Coliru)
As Daniel says in his answer, the utility of such a thing is limited. The trait doesn't actually test if the type is complete at the point in the code where you query, it tests if the type was complete at the point in the program where the trait was first instantiated for a given type.