このコードが無効だったらいいのにと思います。しかし、それは概念的には健全であり、Comeauは受け入れませんが、GCCはそれを受け入れます。
template< typename > struct t;
template<> struct t< int > {} r; // Bad declarator! Don't pee on the carpet!
(編集:上記はコンパイルされますが、どのスコープr
にも宣言されていないようですので、基本的に無視されます。)
明示的な特殊化は、テンプレートとクラスの間の一種のネザー領域に入力されます。明示的な特殊化によって宣言された型は、定義されると完了します。コンパイラの観点からは、これはテンプレートではありません。パラメータ化されたテンプレートの場合、オブジェクトを宣言することは不可能です。§14/3を検討してください:
テンプレート宣言、明示的な特殊化、または明示的なインスタンス化では、宣言内のinit-declarator-listに最大で1つの宣言子を含める必要があります。このような宣言を使用してクラステンプレートを宣言する場合、宣言子は許可されません。
「クラステンプレートの宣言に使用される」とはどういう意味ですか?明らかに、プライマリテンプレートはクラステンプレートを宣言します。また、§14.5.5/ 1(FDIS番号)によると、部分的な特殊化も同様です。
クラステンプレート名がsimple-template-idであるテンプレート宣言は、simple-template-idで指定されたクラステンプレートの部分的な特殊化です。
ただし、明示的な特殊化に関しては、標準はトークンシーケンスが前に付いた宣言の観点から説明していますtemplate<>
。テンプレートのように見え、template-nameという名前が付けられていますが、テンプレートを宣言していないようです。
本当に奇妙なことは、§14/3が宣言者の数を「最大で1つ」に制限していることです。関数テンプレート宣言、明示的な特殊化、またはインスタンス化には、宣言子が1つだけ必要です。クラステンプレートを含むすべての宣言は、正確にゼロでなければなりません…明示的な特殊化を除いて、それは亀裂を通り抜けているようです。忠実に、GCCは許可することを拒否します
template<> struct t< int > {} r, s; // Offer valid one per specialization.
私はGCCの解釈に同意する傾向がありますが、それはナンセンスかもしれません。残念ながら、欠落しているセミコロンを検出する機能が阻害されている可能性があります。許可される宣言子の数を正確にゼロにしてください。