C++任何非类型参数的模板专用化

C++ template specialization with any non-type parameter

本文关键字:专用 任何非 类型参数 C++      更新时间:2023-10-16

我想专门化一个模板。专用化将具有非类型模板参数的另一个模板作为一种类型。我希望专用化适用于非类型参数的任何值。我可以专门针对特定的非类型值,但通常我不知道该怎么做。

例如:

template<typename T, int N>   // first definition
struct A;
template<typename T>          // second definition
struct B;
template<>                    // this compiles, N is fixed
struct B<A<float,1>>;
template<>              // For general N this doesn't compile, says
struct B<A<float,int>>;  // "expected a constant of type ‘int’, got ‘int’"

有没有办法完成它,这样如果参数为 A,我就有 B 的特化,无论 A 的 int N 值是多少?

这不起作用的原因是您将 int 类型作为模板参数传递,您需要一个整数值。要允许任何整数值作为参数,您应该编写类似

template<int P> // For any int value P
struct B<A<float,P>>;

而不是

template<> 
struct B<A<float,int>>; 

template<int N> 
struct B<A<float, N>>;

第一个不起作用,因为A需要一个类型和一个int,而不是两个类型。

我希望专用化适用于非类型参数的任何值。

我的建议确实会这样做。

B<A<float, 1>> b1;     // Uses the specialization
B<A<float, 200>> b2;   // Also uses the specialization

专业如:

template<>
struct B<A<float,int>>{...};

不正确,因为声明template<typename T, int N> struct A;声明 N 是类模板的类型为int的模板非类型/非模板参数。并且它不能用类型代替(在这种情况下int)。

在这种情况下,应该只提供一个值参数,并且由于希望对任何值进行专用化,但只能使用一种类型(在以下示例中float),首先,值作为通用情况的表示形式应出现在template< ___ >中,以便使用它来定义术语B< _____ >

在这种情况下有 2 个选项,例如:

template<int N>
struct B<A<float,N>>{...};

或者像:

template<auto N>
struct B<A<float,N>>{...};

在这两种情况下,编译器都准备查找一个值来替换N作为模板非类型/非模板参数。

最后,类模板B可以像这样使用:

B<A<float, 666> > possessed_object;

另请注意,如果N的类型与int不同,例如,如果它是size_t的,当使用第二个选项(带auto的选项)时,例如:

template<typename T, size_t N> 
struct A{...};
template<auto N>
struct B<A<float,N>>{...};

然后(有保证的)用法变成:

B<A<float, size_t(666)> > possessed_object;

尽管在某些实现中这可能无关紧要,并且第一个提到的用法可能仍然可以使用。

祝你好运!