为什么默认情况下隐藏模板基类的公共成员类型? [英] Why is a template base class' public member types hidden by default?

查看:38
本文介绍了为什么默认情况下隐藏模板基类的公共成员类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

template<typename T>
struct A
{
    using U = T;
};

template<typename T>
struct B : A<T>
{
    B(typename A<T>::U) {} // okay
    B(U) {} // error: unknown type name 'U'
};

int main()
{
    return typename B<int>::U{}; // okay
}

为什么默认隐藏模板基类的公共成员类型?

推荐答案

进一步研究的搜索词是两阶段名称查找".

The search term for further research is "two-phase name lookup".

简而言之,编译器尝试在定义模板的地方解析尽可能多的模板使用的名称.一些名称 - 所谓的从属名称"- 此时无法解析,必须推迟到模板实际实例化并知道其参数.粗略地说,这些是从语法中出现的名称,取决于模板参数.

In short, the compiler tries to resolve as many names used by the template as possible at the point where the template is defined. Some names - so-called "dependent names" - cannot be resolved at this point, and have to be deferred until the template is actually instantiated and its parameters become known. Roughly, these are names that appear from the syntax to depend on the template parameters.

U 本身不是依赖名称,因此编译器会在编译 B 的定义时尝试解析它.它此时无法查看 A<T> 内部 - 它不知道 T 将是什么,或者是否将有 的特化T 的一个 可能会也可能不会声明一个名为U 的成员.然后查找没有找到 U 的声明,因此出现错误.

U by itself is not a dependent name, and so the compiler tries to resolve it while compiling the definition of B. It cannot look inside A<T> at this time - it doesn't know what T is going to be, or whether there's going to be a specialization of A for that T that may or may not declare a member named U. The lookup then doesn't find a declaration for U, hence the error.

UA<T>::U 中是一个依赖名称,它的查找被推迟到 B 被实例化.此时,编译器还会实例化 A 并可以在其中查找 U 的声明.

U in A<T>::U is a dependent name, its lookup is deferred until B<int> is instantiated. At that point, the compiler also instantiates A<int> and can look inside it for the declaration of U.

这也是你需要在typename A<T>::U中写typename的原因.编译器无法查找依赖名称 U 的声明,但它至少需要知道它是类型还是非类型,因为低级词法分析依赖于此(经典的例子是 X*Y; 可以被解析为一个指针的声明,或者一个使用乘法的表达式,这取决于 X 是否是一个类型).所以规则是,除非前面有 typename 关键字,否则依赖名称被假定为引用非类型.

This is also why you need to write typename in typename A<T>::U. The compiler cannot look up the declaration of the dependent name U, but it needs to know at least whether it's meant to be a type or a non-type, as the low-level lexical analysis depends on that (the classic example is that X*Y; could be parsed as a declaration of a pointer, or an expression using multiplication, depending on whether X is a type). So the rule is, the dependent name is assumed to refer to a non-type unless preceded by typename keyword.

这篇关于为什么默认情况下隐藏模板基类的公共成员类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆