Base<T> — зависимый базовый класс, поэтому его поля не находятся обычным поиском имени i при разборе шаблона. Используйте this->i или явное Base<T>::i.
template <typename>
Base<T> — зависимый базовый класс, поэтому его поля не находятся обычным поиском имени i при разборе шаблона. Используйте this->i или явное Base<T>::i.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
template struct Base { int i = 0; };
template <typename T> struct Deriv : Base<T> { void foo() { i = 1; // error: 'i' was not declared in this scope } };
struct Foo : Deriv<Foo> { void bar() { i = 2; } };
Ответ
Base<T> — зависимый базовый класс, поэтому его поля не находятся обычным поиском имени i при разборе шаблона. Используйте this->i или явное Base<T>::i.
Исправление:
template<typename T>
struct Deriv : Base<T> {
void foo() { this->i = 1; }
};
this->i делает обращение зависимым и позволяет разрешить его при инстанцировании. Ещё один вариант — using Base<T>::i; в классе Deriv.
Foo уже не шаблон и наследует конкретный Deriv<Foo>, поэтому в его bar обычный поиск видит унаследованное i. Это отличие этапов поиска имён, а не отсутствие поля в Base.
Источник: eel.is.