如何解决在嵌套名称说明符中使用 simple-template-id 是否明确表示类模板特化?
struct A{
template<typename U>
void T(){}
};
struct B{
template<typename U>
struct T{
using type = U;
};
};
struct C:A,B{
};
int main(){
C::T<int>::type d;
}
这个 example 不被 GCC 和 Clang 接受。
类或命名空间成员或枚举器的名称可以在应用于表示其类的嵌套名称说明符的 :: 范围解析运算符([expr.prim.id.qual])之后引用,命名空间或枚举。如果嵌套名称说明符中的 :: 范围解析运算符前面没有 decltype-specifier,则查找 :: 之前的名称仅考虑其特化为类型的名称空间、类型和模板。
这意味着在查找模板名称 T
的声明时,T
的特化应表示此上下文中的类型。另一方面,根据 class.member.lookup#4
如果 C 包含名称为 f 的声明,则声明集包含在 C 中声明的每个 f 声明,这些声明满足发生查找的语言结构的要求。
同样,当在 T
的范围内查找模板 C
时,该查找只应考虑那些特化为类型的模板。 C
的范围没有 T
的任何声明,因此将在其每个基类中为 S(T,C)
执行查找。 T
中的模板 A
不满足要求。同时,在T
范围内声明的模板B
确实满足要求。因此查找没有歧义,B::T
是唯一的结果。这意味着 C::T<int>::type d
应该是格式良好的。为什么 GCC 和 Clang 都拒绝这个例子?它可以被认为是两者的错误吗?如果我遗漏了什么,这个例子应该格式错误的原因是什么?
解决方法
查找 T
所需的 lookahead 取决于 ::
,即使 <
的解释取决于 {{1} 的含义} 被认为是不可取的。因此,查找后跟 T
的名称不受类型和命名空间的限制,无论以后找到任何 <
。 P1787R6 修复了这个问题,将特殊查找限制为立即后跟 >::
的标识符(因为其他类型的名称无论如何都不能引用类型或命名空间)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。