在何处声明类成员模板的部分专用化

Where to declare partial specializations of class member templates?

本文关键字:专用 声明 成员 在何处      更新时间:2023-10-16

在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*> { };

那么,在非命名空间范围内类模板部分专用化怎么样?标准允许吗?我在哪里可以找到相关文本?

具体来说,我的示例是否有效(如果封闭类是模板,它是否仍然有效)?如果不是,当前的编译器如上所述编译我的示例是错误的吗?

这似乎有点令人困惑,因为我同意你引用的段落似乎不允许类定义中的部分专业化。但是,有 [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

结束示例 ]

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


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