如何检测类型是否是泛型类型列表之一
如果我有
template <typename T> struct A;
template <typename T> struct B;
template <typename T> struct C;
template <typename T> struct D;
如果某个候选类型X是其中之一,那么最紧凑的测试方法是什么?我正在寻找类似的东西
boost::enable_if< is_instantiation_of_any<X,A,B,C,D> >
但是 A、B、C 和 D 是模板,所以我不确定如何构建上述内容。
回答
不确定是否存在 a 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;
}
输出:
101
要获得符合 C++11 的解决方案,我们可以使用Jarod42s 答案之一中的巧妙技巧:
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; };
以is_instantiation_of_anyC++11 友好的方式编写:
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;
};
完整的 C++11 示例
- These template questions always snipe me too https://xkcd.com/356/
- Tagged C++11, so fold expression should be replaced. (there is a [trick for `all_of`](https://stackoverflow.com/a/37148692/2684539) to avoid recursion, `any_of` is just the negation of `none_of` (which is `all_of` with negated condition)).
- @bradgonesurfing not sure how serious Ayxans comment was, the thing is that "arbitrary number of mixed type and non-type parameters" is not just x2 or x3 more complex than what I presented in my answer but its a whole different story.