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

结束示例]

恕我直言,这不是很明确;它不允许类定义中的部分特化,而是(对我来说,似乎是)指定如何处理成员模板特化。


另请参阅核心语言问题 708EWG 问题 41

于 2013-11-08T16:09:18.250 回答