在实例化封闭类模板之后,我们可以声明模板类成员的部分专用化吗

Can we declare a partial specialization of a template class member after instantiation of the enclosing class template?

本文关键字:成员 声明 专用 我们 实例化 之后      更新时间:2023-10-16

让我们考虑这个简单的例子:

template<class T>
struct A{
template<class V,class=void>
struct B{
static const int value=1 ;
};
};
#ifdef PRE_INSTANTIATION
A<int> a;
#endif
#ifdef PARTIAL_SPECIALIZATION_OF_TEMPLATE_MEMBER
template<class T>
template<class V>
struct A<T>::B<double,V>{
static const int value = 2;
};
#else //PARTIAL_SPECIALIZATION_OF_SPECIALIZATION_MEMBER
template<>
template<class V>
struct A<int>::B<double,V>{
static const int value = 2;
};
#endif
static_assert(A<int>::B<int>::value==1,"");
#if __clang__ && PRE_INSTANTIATION && PARTIAL_SPECIALIZATION_OF_TEMPLATE_MEMBER
//Unexpected =>
static_assert(A<int>::B<double>::value==1,"");
#else //Expected =>
static_assert(A<int>::B<double>::value==2,"");
#endif

clang没有考虑CCD_ 1的部分专门化。GCC总是考虑它。只有当我们在声明A<T>::B的部分专门化之前强制A<int>实例化时,clang才会有这种"意外"行为。如果我们声明专用主模板A<int>::B的部分专用化,clang具有预期的行为。

叮当是对的吗?或者这里有没有不可知的UB?


请注意,自c++11支持以来的所有clang版本都有这种行为,自c++11支持以来所有gcc版本都有"预期"行为。此处编码

这个核心语言问题#1755。

根据建议中遵循的方向行为可以标准化[N4900]:

对于给定的实例化类specialization,首选的主要成员模板,partial专业化或完全专业化可以明确声明为

在当前的c++标准中,它没有标准化,结构形成良好,但结果未指明。

据报道,这是clang的错误#17294