Check if two types are of the same template

倾然丶 夕夏残阳落幕 提交于 2019-11-29 15:43:39

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.

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!