代码之家  ›  专栏  ›  技术社区  ›  Alexander Bily

C++two is\u union\u或\u类实现

  •  2
  • Alexander Bily  · 技术社区  · 7 年前

    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> { };
    

    然后,我使用虚拟空类测试了它,并 value 评估为的成员 false .然后我用

    #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::* 是有效的表达式,为什么只有在第二种情况下helper继承自 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编译器进行了测试。

    1 回复  |  直到 7 年前
        1
  •  2
  •   skypjack    7 年前

    考虑一下:

    is_union_or_class1<dummy_type>::value
    

    dummy_type 不是指向类的char类型的数据成员的指针 T 你想要推断。换句话说,这种专门化是为了 (让我说) 类型 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 { };
    

    void\u t 对于那些还在等待C++17的人来说。