Ошибка "не объявлено в этой области" с шаблонами и наследованием
Вот пример кода, который воспроизводит мою проблему:
template <typename myType>
class Base {
public:
Base() {}
virtual ~Base() {}
protected:
int myOption;
virtual void set() = 0;
};
template <typename InterfaceType>
class ChildClass : public Base < std::vector<InterfaceType> >
{
public:
ChildClass() {}
virtual ~ChildClass() {}
protected:
virtual void set();
};
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
myOption = 10;
}
Мое использование в main()
:
ChildClass<int> myObject;
Я получаю следующую ошибку (gcc 4.4.3 в Ubuntu):
myOption не был объявлен в этой области
Если бы мой ChildClass был бы без нового параметра шаблона, это бы работало нормально, то есть:
class ChildClass : public Base < std::vector<SomeConcreteType> >
редактировать
Мне удалось решить это, если мой метод set выглядит следующим образом:
Base<std::vector<InterfaceType> >::myOption = 10;
Работает нормально. Тем не менее, хотя не уверен, почему мне нужно указать все параметры шаблона.
2 ответа
myOption
не является зависимым именем, то есть оно не зависит явно от аргументов шаблона, поэтому компилятор пытается найти его заранее. Вы должны сделать его зависимым именем:
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
this->myOption = 10;
}
Теперь это зависит от типа this
и, следовательно, на аргументы шаблона. Поэтому компилятор свяжет его во время создания экземпляра.
Это называется двухфазным поиском имени.
C++03 14.6.2 Зависимые имена
В определении шаблона класса или члена шаблона класса, если базовый класс шаблона класса зависит от параметра-шаблона, область действия базового класса не проверяется при поиске неквалифицированного имени ни в точке определения класса шаблон или член или во время создания шаблона класса или члена.
Следующий код должен работать.
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
Base<std::vector<InterfaceType> >::myOption = 10;
}