具有任何非类型参数的 C++ 模板特化

C++ template specialization with any non-type parameter

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

例如:

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 的 int N 的值是多少,如果参数是 A,我就可以对 B 进行特化?

而不是

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

使用

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

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

I want the specialization to apply for any value of the non-type parameter.

我的建议确实可以做到这一点。

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

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

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

专业如:

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

不正确,因为声明 template<typename T, int N> struct A; 声明 N 是 class 模板的类型 int 的模板 non-type/non-template 参数。并且它不能被类型替代(在本例中为 int)。

在这种情况下,应该专门提供一个值参数,因为希望对任何值进行专门化,但只有一种类型(以下示例中的float),首先是值的表示作为一般情况应该出现在 template< ___ > 中,因此它可以用来定义术语 B< _____ >

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

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

或喜欢:

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

在这两种情况下,编译器都准备寻找一个值来替代 N 作为模板 non-type/non-template 参数。

最后 class 模板 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;

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

祝你好运!