1
#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(它应该可以是任何值)呢?

4

1 回答 1

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

Coliru 上的工作示例(当然,func可以将 的定义内联到类模板定义中。)

但是,当类模板有许多其他成员时,这可能不是最佳选择,因为您必须重新定义它们:

(§14.5.5/3) [...] 类模板特化是一个独特的模板。类模板部分特化的成员与主模板的成员无关。应定义以需要定义的方式使用的类模板偏特化成员;主模板成员的定义永远不会用作类模板部分特化成员的定义。[...]

在某些情况下,最好声明一个单独的类模板,仅将这个函数作为成员(可能是静态成员,如果不需要访问其他成员 - 可能将需要访问成员作为显式函数参数传递),然后从实际的类模板中引用它(以避免必须部分专门化整个类模板)。

于 2013-06-02T08:02:28.300 回答