Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SFINAE to check if the type is complete or not [duplicate]

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.

like image 695
Nikki Chumakov Avatar asked Jan 14 '14 16:01

Nikki Chumakov


2 Answers

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 <typename T>
struct is_complete_helper {
    template <typename U>
    static auto test(U*)  -> std::integral_constant<bool, sizeof(U) == sizeof(U)>;
    static auto test(...) -> std::false_type;
    using type = decltype(test((T*)0));
};

template <typename T>
struct is_complete : is_complete_helper<T>::type {};

and use it to check for is_defined_hash_type<T> by determining if hash<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.

like image 84
Casey Avatar answered Oct 25 '22 13:10

Casey


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 define T, the definition of is_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).

like image 43
Daniel Frey Avatar answered Oct 25 '22 13:10

Daniel Frey