c++ - 在嵌套名称说明符中使用 simple-template-id 是否明确表示类模板特化?

标签 c++ templates language-lawyer name-lookup

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 都不接受。
根据 basic.lookup.qual#1

The name of a class or namespace member or enumerator can be referred to after the​::​ scope resolution operator ([expr.prim.id.qual]) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a​::​ scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that ​::​ considers only namespaces, types, and templates whose specializations are types.


这意味着在查找模板名称 T 的声明时,专精T在此上下文中应表示一种类型。另一方面,根据 class.member.lookup#4

If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C that satisfies the requirements of the language construct in which the lookup occurs.


同样,在查找模板时 TC范围内,此查找仅应考虑那些专门化为类型的模板。 C范围T 没有任何声明,因此将为 S(T,C) 执行查找在它的每一个基类中。模板TA不满足要求。同时,模板TB 的范围内声明确实满足要求。所以查找没有歧义,B::T是唯一的结果。这意味着 C::T<int>::type d应该是良构的。为什么 GCC 和 Clang 都拒绝这个例子?它可以被认为是两者的错误吗?如果我错过了什么,这个例子应该格式错误的原因是什么?

最佳答案

前瞻需要查找 T取决于 ::偶为解读<取决于T的含义被认为是不受欢迎的。因此,查找名称后跟 <不受类型和命名空间的限制,无论任何 >::后来发现。 P1787R6修复了这个问题,将特殊查找限制为标识符 立即其次是 :: (因为其他类型的名称无论如何都不能引用类型或命名空间)。

关于c++ - 在嵌套名称说明符中使用 simple-template-id 是否明确表示类模板特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66383078/

相关文章:

c++ - 如何将 typename 传递给我不想模板化的类?

C++仿函数编译错误

c++ - std::is_invocable 的奇怪行为

c++ - 简单快速读取过程

c++ - 使用 Magick++ 加载 ICC 配置文件

c++ - 以相反的顺序存储整数值

C++ 列表初始化允许多个用户定义的转换

c++ - 研究简单的代码反汇编输出和内存映射

c++ - 是否为未使用的模板类方法生成目标代码?

c++ - 对迭代器的钳制是否有效