"не объявлена в этой области" ошибка с шаблонами и наследованием
Вот пример кода, который воспроизводит мою проблему:
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> >
Изменить
Мне удалось его решить, если мой метод набора выглядит так:
Base<std::vector<InterfaceType> >::myOption = 10;
Он отлично работает. Тем не менее, хотя и не уверен, почему мне нужно указать все параметры шаблона.
Ответы
Ответ 1
myOption
не является зависимым именем, то есть оно не зависит от аргументов шаблона явно, поэтому компилятор пытается найти его раньше. Вы должны сделать это зависимым именем:
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
this->myOption = 10;
}
Теперь это зависит от типа this
и, следовательно, от аргументов шаблона. Поэтому компилятор свяжет его во время создания экземпляра.
Это называется Двухфазное имя поиска.
Ответ 2
С++ 03 14.6.2 Зависимые имена
В определении шаблона класса или члена шаблона класса, если базовый класс шаблона класса зависит от параметра шаблона, область базового класса не проверена при неквалифицированном имени поиск в точке определения шаблона класса или член или во время создания шаблона или члена класса.
Следующий код должен работать.
template <typename InterfaceType>
void ChildClass<InterfaceType>::set()
{
Base<std::vector<InterfaceType> >::myOption = 10;
}