Trait to check if some specialization of template class is base class of specific class

后端 未结 2 437
囚心锁ツ
囚心锁ツ 2020-12-10 14:37

There is std::is_base_of in modern STL. It allow us to determine whether the second parameter is derived from first parameter or if they are the same classes bo

2条回答
  •  温柔的废话
    2020-12-10 15:05

    If you can assume that a derived type uses a public inheritance from B (and so the upcasting is possible), then you can use the following SFINAE:

    namespace detail
    {
        template 
        struct is_derived_from_B
        {
            using U = typename std::remove_cv<
                                      typename std::remove_reference::type
                                    >::type;
    
            template 
            static auto test(B*)
                -> typename std::integral_constant>::value>;
    
            static std::false_type test(void*);
    
            using type = decltype(test(std::declval()));
        };
    }
    
    template 
    using is_derived_from_B = typename detail::is_derived_from_B::type;
    

    Tests:

    static_assert(is_derived_from_B>::value, "!");
    static_assert(!is_derived_from_B::value, "!");
    static_assert(!is_derived_from_B>::value, "!");
    static_assert(!is_derived_from_B>::value, "!");
    

    DEMO 1

    It can be generalized to accept any base class template:

    namespace detail
    {
        template