Search code examples
c++sfinaetype-traits

Check if two types are of the same template


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 despite the inner elements being of different types.

It's important that the check is made at compile time (that's why the function is constexpr).

#include <iostream>
#include <type_traits>
#include <vector>

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

int main()
{
  std::vector<int> v1(100,0);
  std::vector<double> v2(100,0);
  std::cout << CheckTypes(v1,v2);
}

Solution

  • 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.