模板实例化有两个阶段(“两阶段名称查找”)。
在第一阶段,所有非依赖名称都被解析(查找)。在第二阶段,从属名称被解析。
依赖名称是依赖于模板参数的名称,例如:
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
    }
顺便说一句,我曾经写过这个->在我的低频博客中不仅是风格问题。