c++ - 如何检测类型是否为通用类型列表之一

标签 c++ c++11 template-meta-programming enable-if

如果我有

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是模板,因此我不确定如何构造以上内容。

最佳答案

不确定是否存在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,ca,b,c,truea均为b时,其相当聪明的ctrue才相同。 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

关于c++ - 如何检测类型是否为通用类型列表之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66422250/

相关文章:

c++ - 为什么这段模板代码在VS2010中有效,在VS2012中却无效?

c++ - 元函数重载 C++ - enable_if

c++模板运算符未找到匹配项

c++ - 如何在运行时检测 C 中的操作系统

c++ - vector 增长时如何强制执行 move 语义?

c++11正则表达式比python慢

c++ - 如何使用正则表达式捕获多行?

c++ - new不分配内存?

c++ - 嵌套成员类型识别

c++ - Boost Test BOOST_CHECK_EQUAL 类型可转换为数组