This question already has an answer here:
- How to write `is_complete` template? 7 answers
Is it possible to check with SFINAE if the type is completely defined?
E.g.
template <class T> struct hash;
template <> struct hash<int> {};
// is_defined_hash_type definition...
enum Enum { A, B, C, D };
static_assert ( is_defined_hash_type<int> ::value, "hash<int> should be defined");
static_assert (! is_defined_hash_type<Enum>::value, "hash<Enum> should not be defined");
The solution should not modify the hash struct.
The best I came up with so far is the following, which requires at least a
typedef
with a common name in all the specialization ofhash
:The syntax is pretty ugly, due to the added parameter (needed to trigger SFINAE). If you think it may be the way to go, I'll try to clean it up further.
Disclaimer: I am by no means a C++11 expert, so I may have missed some points using new features. In that case fire at will and I'll try to correct the answer.
It's not possible. The reason is that you'd have to define
is_defined_hash_type<T>
but there can be only one definition. But if you later defineT
, the definition ofis_defined_hash_type<T>
would yield a different result, hence a different definition, and that's not allowed. It's a violation of the ODR (One definition rule).You can make an
is_complete
type trait, using the fact that it is ill-formed to evaluatesizeof(T)
for an incomplete typeT
:and use it to check for
is_defined_hash_type<T>
by determining ifhash<T>
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.