Вопрос по inheritance, c++ – Почему я не могу использовать переменную родительского класса, который является шаблоном класса?

6

хиджры

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

b.h

<code>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;
}
</code>

почему происходит ошибка, когда я не используюthis->?

Могу ли я опуститьthis-> с использованием какого-либо метода?

(Я исправил некоторые ошибки)

Это настоящий код? После определений классов нет конечных точек с запятой и оператора области видимости дляint B<T>:f() неверный плюс нет точки с запятой в строке ошибки. hmjd
О, это просто опечатка. Я починил это Gimun Eom
Иоахим Пилеборг дал тебе ответ. Кроме того, у предоставленного кода есть другие проблемы, препятствующие его компиляции. Anonymous

Ваш Ответ

2   ответа
12

На первом этапе все независимые имена разрешаются (ищется). На втором этапе разрешаются зависимые имена.

Зависимое имя - это имя, которое зависит от параметра шаблона, например :

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 нетa видно, потому что компилятор не может анализировать шаблоны базового класса на этапе 1, потому что шаблоны могут быть специализированными и в момент создания экземпляра, который может быть удален от первичного объявления шаблона, другой специализации, не имеющей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
    }

Кстати, я однажды написал это-> это не только вопрос стиля в моем очень низкочастотном блоге.

Зависимое имя - это имя, которое не зависит от параметра шаблона -> Зависимое имя - это имя, которое зависит от параметра шаблона:) 陳 力
@ czxyl: Почти пол десятилетия, чтобы раскрыть эту ошибку: D Спасибо за подсказку:) Sebastian Mach
1

B является шаблоном, и поэтому его имена не зависят и, следовательно, должны просматриваться при определении шаблона, а не при его создании. Однако во время определения шаблона зависимые имена неизвестны (могут существовать специализации шаблона базового класса @A (который до сих пор не был замечен), компилятор не может преобразовать неквалифицированное имя в базовый класс. Вы можете ввести имя в текущую область с помощьюthis-> квалификация, с префиксомA<T>:: или сusing декларация:

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

Также обратите внимание, что вы пропустили точку с запятой после объявлений класса и строку, помеченную символом// Error комментарий.

-1:this-> не имеет ничего общего с областью видимости. Sebastian Mach
-1: «его имена не зависят и, следовательно, должны быть просмотрены» -> Это неправильно. Могут быть имена членов, которые зависят. Пример: Ideone.com / zIa7k Sebastian Mach
«Зависимые имена неизвестны» -> Это не имеет смысла в языке С ++. Имя может быть зависимым или нет, например, с именем типа T,A<T>::x является зависимым именем,x не является. Для вас, как для программиста, может иметь смысx является зависимым именем, но технически,x являетсян зависимое имя. Sebastian Mach
+ 1: за упоминание альтернативthis. Sebastian Mach
Извините, "... нельзя разрешить зависимые имена (...), поэтому компилятор не может определить, определен ли он в базовом классе", было бы более уместно. Michael Wild

Похожие вопросы