我有一个特征可以返回有关某个类的一些信息,例如维数:
template< typename T >
struct NumDims;
对于&#34;正常&#34;这课很容易专攻:
template<>
struct NumDims< MyClass >: std::integral_constant< unsigned, 3 >{};
但我有一些沉重的模板类,它们都有一个共同的静态constexpr,如:
template< class T, class U, class V, bool x, bool y, bool z >
struct TemplateClass{
static constexpr unsigned numDims = ...;
}
一个看起来很丑陋和错误的人:
template< class T, class U, class V, bool x, bool y, bool z >
struct NumDims< TemplateClass<T,U,V,x,y,z> >{
static constexpr unsigned value = TemplateClass<T,U,V,x,y,z>::numDims;
}
我尝试使用可变参数模板:
template< class... T >
struct NumDims< TemplateClass<T...> >{
static constexpr unsigned value = TemplateClass<T...>::numDims;
}
但这会使我的编译器崩溃(gcc 4.8.2):
内部编译器错误:在unify_one_argument中,在cp / pt.c:15506
任何想法都可以做到这一点&#34;探针&#34;方式是什么?
答案 0 :(得分:4)
您的问题是您的TemplateClass
类模板中混合了类型和非类型参数,因此您不能拥有可变参数类型参数。据我所知,目前没有办法混合类型和非类型的参数,没有在非虚拟模板中包装非类型参数。
幸运的是,您可以支持整个问题,并且只有当您传入的类型具有numDims
静态成员时才启用部分特化:
template <typename T, typename = void>
struct NumDims;
template<>
struct NumDims< MyClass >: std::integral_constant< unsigned, 3 >{};
template< class T >
struct NumDims< T, void_t<decltype(T::numDims)> >{
static constexpr unsigned value = T::numDims;
};
这使用了尚未标准的void_t
,因此您可以使用这样的简单实现:
template <typename...>
struct voider { using type = void; };
template <typename... Ts> using void_t = typename voider<Ts...>::type;