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) [...] クラス テンプレートの特殊化は個別のテンプレートです。クラス テンプレートの部分的な特殊化のメンバーは、プライマリ テンプレートのメンバーとは無関係です。定義が必要な方法で使用されるクラス テンプレートの部分的な特殊化メンバーは、定義する必要があります。プライマリ テンプレートのメンバーの定義は、クラス テンプレートの部分的な特殊化のメンバーの定義として使用されることはありません。[...]

場合によっては、この 1 つの関数のみをメンバーとして (他のメンバーへのアクセスが必要ない場合は静的メンバーである可能性があり、アクセス必要なメンバーを明示的な関数引数として渡す可能性があります)、別のクラス テンプレートを宣言することが望ましい場合があります。実際のクラス テンプレート内からそれを参照します (クラス テンプレート全体を部分的に特殊化する必要がないようにするため)。

于 2013-06-02T08:02:28.300 に答える