2

ここで、stackoverflow でいくつかのコメントを見つけました (たとえば、この質問に関するjrokのコメントを参照)。以下の例のように、(明示的な特殊化とは対照的に) クラス メンバー テンプレートの部分的な特殊化が非名前空間スコープで許可されていることを示しています。

class A {
    template <class T, class U>
    class B {};
    template <class U>
    class B<void, U> {};
};

また、この例は gcc と clang の両方で問題なくコンパイルされます。ただし、c++03 標準テキストでは、この問題について 14.5.4 [temp.class.spec] §6 (または c++11 では 14.5.5 §5) しか見つかりません。

クラス テンプレートの部分的な特殊化は、その定義が定義されている任意の名前空間スコープで宣言または再宣言できます (14.5.1 および 14.5.2)。

次の例とともに:

template<class T> struct A {
    class C {
        template<class T2> struct B { };
    };
};

// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
struct A<T>::C::B<T2*> { };

では、名前空間以外のスコープでのクラス テンプレートの部分的な特殊化はどうでしょうか。それらは標準で許可されていますか?また、関連するテキストはどこにありますか?

具体的には、私の例は有効ですか (囲んでいるクラスがテンプレートである場合でも有効でしょうか)? そうでない場合、現在のコンパイラは上記のように私の例をコンパイルするのは間違っていますか?

4

1 に答える 1

0

あなたが引用した段落がクラス定義内の部分的な特殊化を許可していないように見えることに同意するので、これは少し混乱しているようです。ただし、[temp.class.spec.mfunc]/2 があります。

クラス テンプレートのメンバー テンプレートが部分的に特殊化されている場合、メンバー テンプレートの部分的な特殊化は、外側のクラス テンプレートのメンバー テンプレートです。[...] [例:

template<class T> struct A {
    template<class T2> struct B {}; // #1
    template<class T2> struct B<T2*> {}; // #2
};

template<> template<class T2> struct A<short>::B {}; // #3

A<char>::B<int*> abcip; // uses #2
A<short>::B<int*> absip; // uses #3
A<char>::B<int> abci; // uses #1

終了例]

私見これはあまり明確ではありません。クラス定義内での部分的な特殊化は許可されませんが、メンバー テンプレートの特殊化がどのように処理されるかを指定する (私にはそう思われます)。


Core Language Issue 708およびEWG Issue 41も参照してください。

于 2013-11-08T16:09:18.250 に答える