在stackoverflow中,我发现了几条注释(例如参见jrok关于this问题的注释),指出在非命名空间范围内允许类成员模板的部分特化(相反)显式特化),如下例所示:
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*> { };
那么,非命名空间范围内的类模板部分特化如何?它们是否被标准所允许?我在哪里可以找到相关的文字?
具体来说,我的示例是否有效(如果封闭类是模板,它仍然有效)?如果没有,当前编译器是否错误编译我的例子如上所述?
答案 0 :(得分: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
- 结束示例]
恕我直言,这不是很明确;它不会在类定义中允许部分特化,而是(对我来说,似乎)指定如何处理成员模板特化。