不确定是否存在std::is_instantiation_of,但如果所有模板都具有相同数量的参数,则实现它很简单(如果不存在则更复杂)。要检查一个类型是否是任何给定模板的实例化,您只需将其折叠(需要 C++17):
#include<iostream>
#include<type_traits>
template <typename T> struct A;
template <typename T> struct B;
template <typename T> struct C;
template <typename T> struct D;
template <typename T,template<typename> typename X>
struct is_instantiation_of : std::false_type {};
template <typename A,template<typename> typename X>
struct is_instantiation_of<X<A>,X> : std::true_type {};
template <typename T,template<typename> typename...X>
struct is_instantiation_of_any {
static const bool value = ( ... || is_instantiation_of<T,X>::value);
};
int main(){
std::cout << is_instantiation_of< A<int>, A>::value;
std::cout << is_instantiation_of< A<double>, B>::value;
std::cout << is_instantiation_of_any< A<int>,A,B>::value;
}
Output:
101
要获得符合 C++11 的解决方案,我们可以使用 Jarod42s answers 中的这个巧妙技巧:
template <bool ... Bs>
using meta_bool_and = std::is_same<std::integer_sequence<bool, true, Bs...>,
std::integer_sequence<bool, Bs..., true>>;
它相当聪明,true,a,b,c 和 a,b,c,true 只有在 a、b 和 c 都为 true 时才相同。 std::integer_sequence 是 C++14,但我们需要的只是一个在其定义中包含 bool 的类型:
namespace my {
template <typename T,T ...t>
struct integer_sequence {};
}
使用它我们可以将上面的内容重写为:
template <bool ... Bs>
using my_all = std::is_same<my::integer_sequence<bool, true, Bs...>,
my::integer_sequence<bool, Bs..., true>>;
因为"ANY(a,b,c,d,...)" 就是"! ALL( !a, !b, !c, !d,...)",我们可以使用:
template <bool ... Bs>
struct my_any { static constexpr bool value = ! my_all< ! Bs...>::value; };
以 C++11 友好的方式编写 is_instantiation_of_any:
template <typename T,template<typename> typename...X>
struct is_instantiation_of_any {
static const bool value = my_any< is_instantiation_of<T,X>::value ...>::value;
};
Complete C++11 example