C++98 標準は次のように述べています。
[temp.class.spec] 部分的な特殊化宣言自体は、名前検索では見つかりません。
これが明示的な特殊化にも当てはまる場合、クラス テンプレートの明示的/部分的な特殊化の前方宣言が非表示になります。
[temp.class.spec.match] クラスのインスタンス化が必要なコンテキストでクラス テンプレートが使用される場合、インスタンス化がプライマリ テンプレートを使用して生成されるか、部分的な特殊化の 1 つを使用して生成されるかを決定する必要があります。
これは、明示的/部分的な特殊化の選択が、一致する特殊化の (暗黙の) インスタンス化の時点まで行われないことを意味します。これは、クラスを完全に定義する必要がある場合にのみ発生します。
次の例では、前方宣言された明示的な特殊化が持つ唯一の効果は、プログラムのコンパイルを失敗させることです。
namespace N
{
template<class T>
struct S
{
};
typedef S<char> Type; // name lookup finds S<T>
template<>
struct S<char>; // invisible to name lookup
typedef S<char> Type; // name lookup finds S<T>
int f(S<char>*); // name lookup finds S<T>
S<int> object; // implicitly instantiates S<int>
template<>
struct S<int>; // illegal, explicit specialization after instantiation
}
N::S<char>* p = 0; // name lookup finds N::S<T>
int i = f(p); // name lookup finds N::f via ADL
N::S<char> object; // illegal, incomplete type N::S<char>
どちらの場合も、(特殊化を削除する以外に) プログラムをコンパイルする唯一の方法は、インスタンス化する前に両方の特殊化の定義を提供することです。これにより、前方宣言が少し無意味になります。
この動作には、実用的な実際のアプリケーションがありますか? これとは別に、これらの前方宣言が役立つものはありますか?