Check if two types are of the same template

后端 未结 3 590
太阳男子
太阳男子 2020-12-21 16:23

I want to check if two types are of the same template. As an example I want the following snippet of code to return true because both objects are vectors despit

相关标签:
3条回答
  • 2020-12-21 16:50

    You can but it take a little of metaprog :

    #include <iostream>
    #include <type_traits>
    #include <vector>
    #include <set>
    
    template <typename Container1, typename Container2> 
    struct CheckTypes_impl
    {
        constexpr static bool check (Container1 , Container2 ) { return false; }
    };
    
    template <
        template <class...> class Container1, class...  args1 ,  class...  args2 > 
    struct CheckTypes_impl<Container1<args1...>,Container1<args2...>>
    {
        constexpr static bool check (Container1<args1...> , Container1<args2...> ) { return true; }
    };
    
    
    template < 
            template <class...> class Container1,
            class ... args1,
            template <class...> class Container2,
            class ... args2
        > constexpr bool CheckTypes(Container1<args1...> c1, Container2<args2...> c2)
    {
        return CheckTypes_impl<Container1<args1...>,Container2<args2...>>::check(c1,c2);
    }
    
    int main()
    {
      std::vector<int> v1(100,0);
      std::vector<double> v2(100,0);
      std::set<int> s;
      std::cout << CheckTypes(v1,v2)  << std::endl;
      std::cout << CheckTypes(v1,s)  << std::endl;
    }
    

    run : https://wandbox.org/permlink/OTuQfl7UBlbxgtCO

    Update : You need " template class Container1, class..." because vector don't take 1 template param, but 2. In the general case you don't know how many default parameters will be used

    0 讨论(0)
  • 2020-12-21 16:53

    Here you go:

    template <class T, class U>
    struct are_same_template : std::is_same<T, U>
    {};
    
    template <template<class...> class T, class T1, class T2>
    struct are_same_template<T<T1>, T<T2>> : std::true_type
    {};
    
    template <class T, class U>
    constexpr bool CheckTypes(T, U)
    {
        return are_same_template<T, U>::value;
    }
    

    Demo: http://coliru.stacked-crooked.com/a/8533c694968f4dbb


    This works by providing a specialization of are_same_template that discard the template argument types:

    template <template<class...> class T, class T1, class T2>
    struct are_same_template<T<T1>, T<T2>>
    

    Even if T1 and T2 differ (the template argument types), are_same_template is a true type:

    are_same_template<T<T1>, T<T2>> : std::true_type
    

    About template<class...> instead of template<class>: this is to accomodate the fact than std:: containers have implicit template arguments. Thanks to ConstantinosGlynos for making me aware of it.

    0 讨论(0)
  • 2020-12-21 17:08

    Check this post. They provide a way to check if something is a specialization of a template class:

    template<typename Test, template<typename...> class Ref>
    struct is_specialization : std::false_type {};
    
    template<template<typename...> class Ref, typename... Args>
    struct is_specialization<Ref<Args...>, Ref>: std::true_type {};
    
    

    And probably do something like this to keep your original interface:

    template <typename Container1, typename Container2> 
    constexpr bool CheckTypes(Container1 c1, Container2 c2) {
        return is_specialization<Container1, std::vector>::value && is_specialization<Container2, std::vector>::value;
    }
    
    

    So you can do something like this:

    int main() {
        std::vector<int> v1(100,0);
        std::vector<double> v2(100,0);
        std::cout << CheckTypes(v1,v2);
        return 0;
    }
    
    
    0 讨论(0)
提交回复
热议问题