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

孤街醉人 提交于 2019-11-30 11:21:39

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.

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).

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 of hash:

template <class T> struct hash;
template <>        struct hash<int> {
    typedef int value_type;
    };

template<class T>
constexpr bool is_defined_hash_type(typename hash<T>::value_type) {
  return true;
}

template<class T>
constexpr bool is_defined_hash_type(T) {
  return false;
}

int main()
{
  static_assert (  is_defined_hash_type< int >(0), "hash<int> should be defined");
  static_assert (! is_defined_hash_type< double>(0), "hash<Enum> should not be defined");
  return 0;
}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!