6

template <typename T>
class A
{
    public:
    int a;
}

bh

template <typename T>
class B : public A<T>
{
   public:
   int f();
}

template <typename T>
int B<T>::f()
{
    int t;
    t = this->a; //Okay
    t = a //Error
    return 0;
}

为什么我不使用时会发生错误this->

我可以this->用某种方法省略吗?

(我修正了一些错误)

4

2 回答 2

15

模板实例化有两个阶段(“两阶段名称查找”)。

在第一阶段,所有非依赖名称都被解析(查找)。在第二阶段,从属名称被解析。

依赖名称是依赖于模板参数的名称,例如:

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
    }

顺便说一句,我曾经写过这个->在我的低频博客中不仅是风格问题。

于 2012-04-16T09:19:10.953 回答
1

B是一个模板,因此它的名称是非依赖的,因此必须在定义模板时查找,而不是在实例化模板时查找。但是,在定义模板时,依赖名称是未知的(可能存在A迄今为止尚未看到的基类模板的特化),编译器无法将非限定名称解析为基类。您可以通过this->限定将名称带入当前范围,方法是在其前面加上A<T>::using声明:

template <typename T>
class B : public A<T>
{
   public:
   using A<T>::a;
   int f();
};

// Error另请注意,您在类声明和标有注释的行之后缺少分号。

于 2012-04-16T09:31:16.453 回答