C++ 两个 is_union_or_class 实现

标签 c++ templates type-traits

我尝试实现 is_union_or_class,首先使用以下方法不使用 void_t:

#include <type_traits>

    namespace detail {
        template <class T>
        struct is_union_or_class_helper1 : public std::false_type { };
        template <class T>
        struct is_union_or_class_helper1<char T::*> : public std::true_type { };
    }

template <class T>
struct is_union_or_class1 : public detail::is_union_or_class_helper1<T> { };

然后我使用虚拟空类和评估为 falsevalue 成员对其进行了测试。然后我使用 void_t 重试它,如下所示:

#include <type_traits>

template <class...>
using void_t = void;

    namespace detail {
        template <class T, class = void_t<T>>
        struct is_union_or_class_helper2 : public std::false_type { };
        template <class T>
        struct is_union_or_class_helper2<T, void_t<char T::*>> : public std::true_type { };
    }

template <class T>
struct is_union_or_class2 : public detail::is_union_or_class_helper2<T> { };

这次它的计算结果正确为true。为什么结果不同?两个助手在 char T::* 是有效表达式的情况下都更加专业,为什么只有在第二种情况下助手才继承自 true_type?测试代码如下:

struct dummy_type { };

int main(int argc, char** argv) {
    std::cout << is_union_or_class1<dummy_type>::value << "\n";
    std::cout << is_union_or_class2<dummy_type>::value << "\n";
}

我编译了此代码并使用 MSVC 2015 编译器进行了测试。

最佳答案

考虑一下:

is_union_or_class1<dummy_type>::value

dummy_type 不是指向要推导的类 T 的 char 类型数据成员的指针。换句话说,对于dummy_type(让我说)不匹配类型char T::*,此特化被丢弃。
因此,选择类模板并继承自 std::false_type:

template <class T>
struct is_union_or_class_helper1 : public std::false_type { };

像这样的东西会起作用:

    template <class T, typename = T>
    struct is_union_or_class_helper1 : public std::false_type { };
    template <class T>
    struct is_union_or_class_helper1<T, decltype((char T::*){}, T{})> : public std::true_type { };

这只不过是 void_t 习语的另一种变体。
让我重写一下:

    template <class T, typename = void>
    struct is_union_or_class_helper1 : public std::false_type { };
    template <class T>
    struct is_union_or_class_helper1<T, decltype((char T::*){}, void())> : public std::true_type { };

就是这样,对于那些仍在等待 C++17 的人来说,这是 void_t 惯用法的一种形式。

关于C++ 两个 is_union_or_class 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44999372/

相关文章:

html - 邮件模板中的 CSS 不起作用

c++ - 两个指针什么时候可以比较?

C++ 多态性和模板类

c++ - 如何实现 "either nested type or void"特征?

c++ - 伙伴分配算法 - 堆扩展

c++ - 如何有效地存储矩形网格?

c++ - 如何从双端队列中删除随机元素

c++ - 为什么 ATOMIC_FLAG_INIT 是假的?

c++ - 来自用作模板参数的指针的类类型