检查两种类型是否属于同一模板

时间:2019-03-28 10:14:01

标签: c++ sfinae typetraits

我想检查两种类型是否属于同一模板。例如,我希望下面的代码片段返回true,因为尽管内部元素的类型不同,但这两个对象都是向量。

重要的是要在编译时进行检查(这就是为什么函数为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);
}

4 个答案:

答案 0 :(得分:2)

您在这里:

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

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


这通过提供are_same_template的特殊化来工作,该特殊化放弃了模板参数类型:

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

即使T1T2(模板参数类型)不同,are_same_template还是真实类型:

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

关于template<class...>而不是template<class>:这是为了适应std::容器具有隐式模板参数的事实。感谢ConstantinosGlynos使我意识到这一点。

答案 1 :(得分:0)

选中此post。它们提供了一种方法来检查某些东西是否是模板类的特化:

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

并且可能会执行以下操作以保留原始界面:

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

因此您可以执行以下操作:

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

答案 2 :(得分:0)

您可以,但是需要一些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;
}

运行: https://wandbox.org/permlink/OTuQfl7UBlbxgtCO

更新:您需要“模板类Container1,类...”,因为矢量不接受1个模板参数,而是2个。在一般情况下,您不知道将使用多少个默认参数

答案 3 :(得分:0)

如果您想检查两个模板模板类是否相同而不专门化它们:

template<template<typename...> class ATT, template<typename...> class BTT>
struct is_same_tt : std::false_type {};

template<template<typename...> class TT>
struct is_same_tt<TT, TT> : std::true_type {};

// example
static_assert(is_same_tt<std::tuple, std::tuple>());
static_assert(!is_same_tt<std::vector, std::list>());