bra*_*ing 6 c++ enable-if template-meta-programming c++11
如果我有
template <typename T> struct A;
template <typename T> struct B;
template <typename T> struct C;
template <typename T> struct D;
Run Code Online (Sandbox Code Playgroud)
如果某个候选类型X是其中之一,那么最紧凑的测试方法是什么?我正在寻找类似的东西
boost::enable_if< is_instantiation_of_any<X,A,B,C,D> >
Run Code Online (Sandbox Code Playgroud)
但是 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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
101
Run Code Online (Sandbox Code Playgroud)
要获得符合 C++11 的解决方案,我们可以使用Jarod42s 答案之一中的巧妙技巧:
Run Code Online (Sandbox Code Playgroud)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 {};
}
Run Code Online (Sandbox Code Playgroud)
使用它,我们可以将上面的内容重写为:
template <bool ... Bs>
using my_all = std::is_same<my::integer_sequence<bool, true, Bs...>,
my::integer_sequence<bool, Bs..., true>>;
Run Code Online (Sandbox Code Playgroud)
而作为"ANY(a,b,c,d,...)"仅仅是"! ALL( !a, !b, !c, !d,...)"我们可以使用:
template <bool ... Bs>
struct my_any { static constexpr bool value = ! my_all< ! Bs...>::value; };
Run Code Online (Sandbox Code Playgroud)
以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;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
154 次 |
| 最近记录: |