简体   繁体   English

模板化类型的特长专长

[英]Trait specialization of templated type

I have a trait to return some information about a class eg the number of dimensions: 我有一个特征可以返回有关类的一些信息,例如维数:

template< typename T >
struct NumDims;

For a "normal" class this is easy to specialize: 对于“普通”类,这很容易专门化:

template<>
struct NumDims< MyClass >: std::integral_constant< unsigned, 3 >{};

But I have some heavy templated classes that all have a common static constexpr like: 但是我有一些繁重的模板化类,它们都有一个共同的静态constexpr,例如:

template< class T, class U, class V, bool x, bool y, bool z >
struct TemplateClass{
    static constexpr unsigned numDims = ...;
}

A specilization looks ugly and errorprone: 指定看起来很丑陋且容易出错:

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;
}

I tried to use variadic templates: 我尝试使用可变参数模板:

template< class... T >
struct NumDims< TemplateClass<T...> >{
    static constexpr unsigned value = TemplateClass<T...>::numDims;
}

But this crashes my compiler (gcc 4.8.2): 但这会使我的编译器(gcc 4.8.2)崩溃:
internal compiler error: in unify_one_argument, at cp/pt.c:15506 内部编译器错误:在unify_one_argument中,在cp / pt.c:15506

Any ideas to do this "the prober" way? 有什么想法可以做这种“探测”方式吗?

Your issue is that you have a mixture of type and non-type parameters in your TemplateClass class template, so you can't have a variadic type parameter. 您的问题是,在TemplateClass类模板中混合使用了类型和非类型参数,因此不能使用可变参数类型参数。 As far as I know, there is currently no way to mix type and non-type arguments like that, short of wrapping the non-type ones in some dummy template. 据我所知,当前没有办法像这样将类型和非类型参数混合在一起,除非将非类型参数包装在一些虚拟模板中。

Fortunately, you can side-step the whole issue and just have a partial specialization which is enabled when the type you pass in has a numDims static member: 幸运的是,您可以numDims整个问题,并且只具有部分专业化功能,当您传入的类型具有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;
};

This uses void_t which is not yet standard, so you can use a simple implementation like this: 这使用了还不标准的void_t ,因此您可以使用如下所示的简单实现:

template <typename...>
struct voider { using type = void; };
template <typename... Ts> using void_t = typename voider<Ts...>::type;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM