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

时间:2018-07-25 07:48:23

标签: c++ c++11 templates language-lawyer

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

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不考虑template B的部分专业化。海湾合作委员会一直认为。仅当在声明A<int>的部分专业化之前强制执行A<T>::B实例化时,clang才具有这种“意外”行为。如果我们声明专用主模板A<int>::B的部分专用,则clang具有预期的行为。

c是正确的吗?还是这里有未诊断的UB?


请注意,自c ++ 11支持以来,所有clang版本均具有此行为,而自c ++ 11支持以来,所有gcc版本均具有“预期”行为。 Code here

1 个答案:

答案 0 :(得分:3)

core language issue #1755

按照建议中的指示,gcc 行为可以标准化[N4090]

  

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

在当前的c ++标准中,它尚未标准化,构造良好,但是结果不确定。

这被报告为clang's bug #17294