如何从专用成员函数访问模板参数?

时间:2013-06-02 07:56:08

标签: c++ templates

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

1 个答案:

答案 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)[...]类模板特化是一个独特的模板。类模板部分特化的成员与主模板的成员无关。将以需要定义的方式使用的类模板部分特化成员应被定义;主模板成员的定义从未用作类模板部分特化的成员的定义。 [...]

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