#include <stdio.h>
template<typename T, int N>
class A
{
public:
void func();
};
template<typename T, int N>
void A<int, N>::func()
{
printf("%d\n", N);
}
int main()
{
A<int, 3> a;
a.func();
return 0;
}
当我尝试编译这段代码时,g ++会给出这些错误:
test.cpp:10:22: error: invalid use of incomplete type ‘class A<int, N>’
test.cpp:4:7: error: declaration of ‘class A<int, N>’
当A :: func不是专门的,当函数也专门用于N时,我才设法编译它。
我如何将A :: func专门用于T和访问N(它应该可以是任何值)?
答案 0 :(得分:4)
如果可以,语法必须是
template<int N>
void A<int, N>::func()
{
printf("%d\n", N);
}
即,模板参数列表中不会提及T
。
但不幸的是,这是不可能的。个别职能(包括成员职能)不能部分专业化。
从标准(关于部分类模板特化的部分):
(§14.5.5/ 2)每个类模板部分特化是一个独特的模板,应为模板部分特化的成员提供定义(14.5.5.3)。
在您的情况下,完成所需内容的最直接方法是部分专门化整个类模板:
template<int N>
class A<int,N>
{
public:
void func();
};
template<int N>
void A<int,N>::func()
{
printf("%d\n",3);
}
Working example of this on Coliru(当然,func
的定义可以内联到类模板定义中。)
但是当类模板有许多其他成员时,这可能不是最佳的,因为你必须重新定义所有成员:
(§14.5.5/ 3)[...]类模板特化是一个独特的模板。类模板部分特化的成员与主模板的成员无关。将以需要定义的方式使用的类模板部分特化成员应被定义;主模板成员的定义从未用作类模板部分特化的成员的定义。 [...]
在某些情况下,最好只使用这一个函数作为成员声明一个单独的类模板(如果不需要访问其他成员,则可能是静态成员 - 可能传递访问的成员需要作为显式函数参数),然后从实际的类模板中引用它(以避免必须部分地专门化整个类模板)。