使用SFINAE检查类型是否完整

Nik*_*kov 16 c++ metaprogramming sfinae c++11

如果完全定义了类型,是否可以使用SFINAE进行检查?

例如

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");
Run Code Online (Sandbox Code Playgroud)

解决方案不应该修改哈希结构.

Cas*_*sey 15

你可以is_complete使用sizeof(T)一个不正确的事实来评估一个不完整的类型,从而制作一个类型特征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 {};
Run Code Online (Sandbox Code Playgroud)

is_defined_hash_type<T>通过确定是否hash<T>完成来使用它来检查.(住在Coliru)

正如丹尼尔在答案中所说,这种事情的效用是有限的.特征实际上并不测试类型是否在您查询的代码中的点完成,它测试类型是否在程序中针对给定类型首次实例化特征的点处完成.


Dan*_*rey 5

这是不可能的.原因是你必须定义,is_defined_hash_type<T>但只能有一个定义.但是如果你以后定义T,那么定义is_defined_hash_type<T>会产生不同的结果,因此产生不同的定义,而这是不允许的.这违反了ODR(一个定义规则).

  • @NikkiChumakov 它需要`#include BOOST_PP_UPDATE_COUNTER()`来增加该值,它不能成为`IS_COMPLETE`宏的一部分,所以不,它仍然不可能以可移植的、符合标准的方式。 (2认同)