Ниже приведена простая иерархия классов со смесью шаблонизированных и не шаблонизированных классов. В комментариях к этому примеру встроена ошибка компиляции, которую я пытаюсь исправить.
Я прочитал несколько других связанных тем здесь на SO и попытался несколько форм ключевого слова «using» безрезультатно.
Я узнал в этих испытаниях, что:
Parent :: parent_ivar_ = 99;
является жизнеспособным синтаксисом, но не знаю, как сообщить компилятору о унаследованном ivar grandparent_ivar_, который я хотел бы установить / использовать в классе Child.
Заранее спасибо!
class GrandParent {
public:
int grandparent_ivar_;
};
template <typename T>
class Parent : public GrandParent {
public:
int parent_ivar_;
};
template <typename T>
class Child : public Parent<T> {
public:
Child() {
// The following stmt produces this compiler error using ubuntu g++:
// templateinheritance.cpp: In constructor ‘Child<T>::Child()’:
// templateinheritance.cpp:20:5: error: ‘grandparent_ivar_’ was
// not declared in this scope
// grandparent_ivar_ = 100;
//
grandparent_ivar_ = 100;
}
};
int main(int argc, char *argv[]) {
Child<int> c;
}
Есть на самом деле два проблемы здесь.
Первая проблема заключается в том, что, как было отмечено в другом ответе, Parent
должен публично наследовать от GrandParent
,
Но это не единственная проблема. Даже с этим исправлением это не скомпилируется. до тех пор Child
конструктор изменился на:
Child() {
this->grandparent_ivar_ = 100;
}
Это довольно нюансированная проблема синтаксического анализа, связанная с шаблонами. Пока шаблон полностью не проанализирован, компилятор не имеет достаточно информации, чтобы знать, что это за хрень grandparent_ivar_
, само собой. Это не объявлено в классе шаблона. Это не какая-то глобальная переменная, которая была объявлена ранее.
Пока шаблон полностью не проанализирован, компилятор действительно не может смотреть на его суперклассы, чтобы увидеть, что там. Может быть, это где grandparent_ivar_
есть, пожалуй. Возможно, нет. Кто знает.
Это грубое, простое, краткое содержание. Суть в том, что при объявлении шаблонов вам нужно немного ослабить компилятор и сделать его более четким. Есть несколько способов сделать это, но самый простой способ — быть более либеральным и прямо сказать «это->Foo«, чтобы использовать некоторые foo
это может в конечном итоге быть извлечено из суперкласса шаблона.
Ваша проблема в том, что Parent
в частном порядке наследует GrandParent
таким образом Child
не могу видеть это.
Если Child
нужен доступ GrandParent
тогда вам нужно будет изменить уровень наследования или предоставить метод Parent
(который Child
Можно видите) что можно использовать для изменения grandparent_ivar_