检查两种类型是否属于同一模板
Check if two types are of the same template
我想检查两种类型是否属于同一模板。作为示例,我希望以下代码片段为 return 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);
}
检查这个 post。他们提供了一种方法来检查某些东西是否是模板的特化 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 {};
并且可能会做这样的事情来保留您的原始界面:
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;
}
给你:
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>>
即使 T1
和 T2
不同(模板参数类型),are_same_template
也是真实类型:
are_same_template<T<T1>, T<T2>> : std::true_type
关于 template<class...>
而不是 template<class>
:这是为了适应 std::
容器具有隐式模板参数的事实。感谢 ConstantinosGlynos 让我意识到这一点。
可以,但需要一点 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
更新:您需要“template class Container1, class...”因为 vector 不采用 1 个模板参数,而是 2 个。在一般情况下您不知道如何将使用许多默认参数
如果您想检查两个模板模板 类 是否相同而不专门化它们:
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>());
我想检查两种类型是否属于同一模板。作为示例,我希望以下代码片段为 return 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);
}
检查这个 post。他们提供了一种方法来检查某些东西是否是模板的特化 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 {};
并且可能会做这样的事情来保留您的原始界面:
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;
}
给你:
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>>
即使 T1
和 T2
不同(模板参数类型),are_same_template
也是真实类型:
are_same_template<T<T1>, T<T2>> : std::true_type
关于 template<class...>
而不是 template<class>
:这是为了适应 std::
容器具有隐式模板参数的事实。感谢 ConstantinosGlynos 让我意识到这一点。
可以,但需要一点 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
更新:您需要“template class Container1, class...”因为 vector 不采用 1 个模板参数,而是 2 个。在一般情况下您不知道如何将使用许多默认参数
如果您想检查两个模板模板 类 是否相同而不专门化它们:
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>());