この質問の続きです。このようなメンバークラスの部分的な特殊化に特に興味があります。
struct FooParent {
template <class>
struct Bar{ };
};
struct Foo: FooParent {
template <class T>
struct Bar<T*> {};
};
私はこれが名前空間スコープ内で実行できることを知っています:
template <class T>
struct Foo::Bar<T*>{ };
しかし、私はまた、具体的に興味イン・クラスの派生クラスのレベルで部分特殊。
前者に遭遇すると、clangとgccの両方が文句を言います。
clangは、明らかに発生しない明示的なテンプレートの特殊化があると述べています。
エラー:クラススコープでの「Bar」の明示的な特殊化
gccはここでは少し冗長ではなく、メンバーテンプレートの特殊化は名前空間スコープで実行する必要があると述べていますが、これは明らかに派生クラスではない場合です。
エラー: 'template struct FooParent :: Bar'の特殊化は名前空間スコープに表示される必要があります
gccは彼のエラーメッセージのここにありますか?
OPの要請に応じて、質問へのコメントで私が言ったことを要約しようとしています。
質問に答えるには[temp.class.spec] / 5で十分だと思います。
特に:
クラステンプレートの部分的な特殊化は、対応するプライマリテンプレートを定義できる任意の名前空間スコープで宣言または再宣言できます[...]。
この場合、実際にそれを支配するのは、プライマリテンプレートを定義できる場所です。
この例では、派生クラスの部分的な特殊化を宣言しようとしています(そして、コンテキストで定義しますが、まずは宣言です)。
簡単に言うと、派生クラスでプライマリテンプレートを定義することはできないため、そのクラスで部分的な特殊化を宣言することもできません。
可能であれば、次のことも可能でした。
struct FooParent {
template <class>
struct Bar;
};
struct Foo: FooParent {
template <class T>
struct FooParent::Bar<T*> {};
};
または、必要に応じてこれ:
struct Foo: FooParent {
template <class T>
struct Bar<T*> {};
};
残念ながら(?)それらは許可されておらず、これはクラステンプレートを特殊化する試みも無効であることを伝えるのに十分です。
とにかく、もう少し考えてみましょう。
プライマリテンプレートは、のメンバー仕様の一部ですFoo
(詳細については、ここを参照してください)。
したがって、質問-そのようなテンプレートをどこで定義できますか?、迅速になり-私はクラスの他のメンバーを定義することができますどこ?。
繰り返しますが、答えは-派生クラスのスコープ内ではありません。
言語弁護士があなたにもっと直接的で率直な説明をしてくれると確信しています。
私はまた、同じ言語の弁護士が、標準の間違ったセクションに言及したことで私を呪うだろうと確信しています。
とにかく、上記のいくつかの例があなたに出発点となることを願っています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加