【问题标题】:Can we declare a partial specialization of a template class member after instantiation of the enclosing class template?我们可以在封闭类模板实例化之后声明模板类成员的部分特化吗?
【发布时间】:2019-01-01 22:57:11
【问题描述】:

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

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 的部分特化。 GCC 总是考虑它。仅当我们在声明 A&lt;T&gt;::B 的部分特化之前强制 A&lt;int&gt; 实例化时,clang 才会出现这种“意外”行为。如果我们声明专用主模板 A&lt;int&gt;::B 的部分特化,则 clang 具有预期的行为。

叮当声对吗?还是这里有未确诊的UB?


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

【问题讨论】:

  • 感觉像是格式错误的 NDR。
  • @PasserBy 我刚刚在标准中找到了this sentence。但我仍然不确定,因为 B 是主模板的部分特化,而不是主模板特化。
  • @PasserBy 最后,这既是标准的不足,又被报告为 clang 错误。

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


【解决方案1】:

这个core language issue #1755

根据推荐中的方向,gcc 行为可以标准化[N4090]

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

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

这被报告为clang's bug #17294

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多