模板实例化有两个阶段(“两阶段名称查找”)。
在第一阶段,所有非依赖名称都被解析(查找)。在第二阶段,从属名称被解析。
依赖名称是依赖于模板参数的名称,例如:
template <typename T>
void foo() {
x = 0; // <- Non-dependent, nothing in that refers to "T".
// Thus looked up in phase 1, therefore, an 'x' must be
// visible.
T::x = 0; // <- Dependent, because it depends on "T".
// Looked up in phase 2, which is when it must be visible.
}
现在,你写:
t = this->a; //Okay
t = a //Error
这正是我所描述的。在好的术语中,t
在阶段 2 中查找,因为this
取决于模板参数。
在第 1 阶段查找错误的术语,因为该名称中的任何内容都不依赖于模板参数。但是在阶段 1, noa
是可见的,因为编译器无法在阶段 1 内省基类模板,因为模板可以被特化并且在实例化点,它可以远离主模板声明,另一个没有 no的特化a
可能可见。
例子:
template <typename T>
struct Base {
};
template <typename T>
struct Derived : Base<T> {
void foo() {
this->a = 0; // As is valid. `this->a` is looked up in phase 2.
}
};
template <> struct Base<int> {
int a;
};
int main ()
{
// The following declarations trigger phase 2 lookup.
Derived<int> di; // valid, because a later specialized
// Base<int> is used and all symbols
// are resolved.
Derived<float> df; // not valid
}
顺便说一句,我曾经写过这个->在我的低频博客中不仅是风格问题。