Подтвердить что ты не робот

"не объявлена ​​в этой области" ошибка с шаблонами и наследованием

Вот пример кода, который воспроизводит мою проблему:

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;

Он отлично работает. Тем не менее, хотя и не уверен, почему мне нужно указать все параметры шаблона.

4b9b3361

Ответ 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;
}