How to determine if a type is derived from a template class?

前端 未结 2 1319
太阳男子
太阳男子 2021-02-13 16:05

How can I determine if a type is derived from a template class? In particular, I need to determine if a template parameter has std::basic_ostream as a base class.

相关标签:
2条回答
  • 2021-02-13 16:44

    Might something like Boost's is_instance_of be what you are after?

    http://www.boost.org/doc/libs/1_46_1/boost/lambda/detail/is_instance_of.hpp

    Here is the short version for 1-argument templates:

    #include <iostream>
    #include <type_traits>
    
    template <template <typename> class F>
    struct conversion_tester
    {
            template <typename T>
            conversion_tester (const F<T> &);
    };
    
    template <class From, template <typename> class To>
    struct is_instance_of
    {
            static const bool value = std::is_convertible<From,conversion_tester<To>>::value;
    };
    
    template <typename T>
    struct foo {};
    
    template <typename T>
    struct bar {};
    
    int main()
    {
            std::cout << is_instance_of<foo<int>,foo>::value << '\n'; // This will print '1'.
            std::cout << is_instance_of<bar<int>,foo>::value << '\n'; // This will print '0'.
    }
    

    Unfortunately, if you try to extend this to variadic templates, with current GCC (4.6.0) it will produce an error message. This SO answer implies that this is currently a problem of GCC and that the variadic template version is supposed to work according to the standard.

    0 讨论(0)
  • 2021-02-13 16:52

    I'm not aware of a short and concise way. But you can abuse overloading again

    template< typename T, typename U >
    std::true_type is_based_impl( std::basic_ostream<T, U> const volatile& );
    std::false_type is_based_impl( ... );
    
    template< typename T >
    bool is_based_in_basic_ostream( T&& t ) {
      return decltype(is_based_impl(t))::value;
    }
    

    It will only detect public inheritance. Note that you can instead detect derivation from ios_base, which may work for you equally well (this test will also be positive for input streams, so it's only of limited applicability)

    std::is_base_of<std::ios_base, T>
    
    0 讨论(0)
提交回复
热议问题