在实例化封闭类模板之后,我们可以声明模板类成员的部分专用化吗
Can we declare a partial specialization of a template class member after instantiation of the enclosing class template?
让我们考虑这个简单的例子:
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
相关文章:
- 使用静态成员声明类时遇到问题
- 错误 C2059:语法错误:从结构成员声明'constant'
- std::d eclare_if 或其他在编译时丢弃成员声明的假设方法
- C++ 成员声明中不允许使用限定名称
- 又一个"未找到成员声明"
- auto f = bind(dist<>,gen) 在成员声明C++失败。未被识别为函数
- C++错误:成员声明末尾的预期“;”
- 静态成员声明 c++11
- 如何将成员声明为指向外部"C"函数的指针?
- C++11 - 将非静态数据成员声明为 'auto'
- 类成员声明的快捷方式
- libclang 获取成员声明
- 将成员声明与enable_if一起使用
- 找不到成员声明
- C++错误:找不到成员声明
- 找不到c++成员声明
- 成员声明顺序在类中如果彼此依赖,则为最优解
- 将struct的成员声明为uint32_t时额外的字节
- 为什么类的大小取决于成员声明的顺序?以及如何
- 是成员声明`decltype(name)name;`在第一个名称引用封闭作用域的本地结构中允许