Смешанная шаблонная / не шаблонная таксономия наследования и наследования членов

Ниже приведена простая иерархия классов со смесью шаблонизированных и не шаблонизированных классов. В комментариях к этому примеру встроена ошибка компиляции, которую я пытаюсь исправить.

Я прочитал несколько других связанных тем здесь на 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;
}

1

Решение

Есть на самом деле два проблемы здесь.

Первая проблема заключается в том, что, как было отмечено в другом ответе, Parent должен публично наследовать от GrandParent,

Но это не единственная проблема. Даже с этим исправлением это не скомпилируется. до тех пор Childконструктор изменился на:

Child() {
this->grandparent_ivar_ = 100;
}

Это довольно нюансированная проблема синтаксического анализа, связанная с шаблонами. Пока шаблон полностью не проанализирован, компилятор не имеет достаточно информации, чтобы знать, что это за хрень grandparent_ivar_, само собой. Это не объявлено в классе шаблона. Это не какая-то глобальная переменная, которая была объявлена ​​ранее.

Пока шаблон полностью не проанализирован, компилятор действительно не может смотреть на его суперклассы, чтобы увидеть, что там. Может быть, это где grandparent_ivar_ есть, пожалуй. Возможно, нет. Кто знает.

Это грубое, простое, краткое содержание. Суть в том, что при объявлении шаблонов вам нужно немного ослабить компилятор и сделать его более четким. Есть несколько способов сделать это, но самый простой способ — быть более либеральным и прямо сказать «это->Foo«, чтобы использовать некоторые foo это может в конечном итоге быть извлечено из суперкласса шаблона.

3

Другие решения

Ваша проблема в том, что Parent в частном порядке наследует GrandParentтаким образом Child не могу видеть это.

Если Child нужен доступ GrandParent тогда вам нужно будет изменить уровень наследования или предоставить метод Parent(который Child Можно видите) что можно использовать для изменения grandparent_ivar_

0

По вопросам рекламы [email protected]