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

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

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;
}
Другие вопросы по тегам