Наследование от шаблонного класса
От: Jaakko Беларусь  
Дата: 14.02.11 12:46
Оценка:
Привет.
Есть шаблонный класс, который описывает enumerator (перечеслитель? не знаю, как корректнее его назвать по-русски)):
template <typename TExternal, typename TInternal = TExternal,
    class TBaseInterface = IEnumerator<TExternal>,
    class TBaseContainer = std::vector<TInternal> >
class CEnumeratorExt : public TBaseInterface

Параметрами шаблона-класса являются:
1. тип принимаемых данных (TExternal).
2. тип хранимых данных (TInternal) — по умолчанию тот же, что и тип принимаемых данных.
3. тип базового интерфейса (TBaseInterface) — набор методов у всех возможных базовых интерфейсов одинаковы, но нельзя сделать единый базовый и от него напрямую наследоваться. По умолчанию — интерфейс, используемый в текущем модуле.
4. тип контейнера (TBaseContainer) — по умолчанию — вектор.

Enumerator'ов в итоге много, они различаются слабо и писать для каждого свой класс — лень, поэтому такой шаблон.
Как правило все Enumerator'ы в качестве контейнера используют вектор, поэтому методы этого шаблонного класса оперируют с вектором (push_back(), back() и всё такое).
Всё бы ничего, но есть несколько классов, которым в качестве контейнера нужен не вектор, а std::set.
Я сделал классы, которые наследуются от приведённого выше шаблона и переопределил нужные методы, но ошибка вылезла в методах шаблона — на тех самых push_back() и back(), мол, нет таких методов у контейнера.

Вопрос — как указать, что методы шаблона не должны компилироваться (специализироваться?), если есть дочерний класс, который переопределяет эти методы.
Как-то так.
Заранее спасибо.
Re: Наследование от шаблонного класса
От: alexsy1  
Дата: 14.02.11 13:29
Оценка:
Здравствуйте, Jaakko, Вы писали:

J>Привет.

J>Есть шаблонный класс, который описывает enumerator (перечеслитель? не знаю, как корректнее его назвать по-русски)):
J>
J>template <typename TExternal, typename TInternal = TExternal,
J>    class TBaseInterface = IEnumerator<TExternal>,
J>    class TBaseContainer = std::vector<TInternal> >
J>class CEnumeratorExt : public TBaseInterface
J>

J>Параметрами шаблона-класса являются:
J>1. тип принимаемых данных (TExternal).
J>2. тип хранимых данных (TInternal) — по умолчанию тот же, что и тип принимаемых данных.
J>3. тип базового интерфейса (TBaseInterface) — набор методов у всех возможных базовых интерфейсов одинаковы, но нельзя сделать единый базовый и от него напрямую наследоваться. По умолчанию — интерфейс, используемый в текущем модуле.
J>4. тип контейнера (TBaseContainer) — по умолчанию — вектор.

J>Enumerator'ов в итоге много, они различаются слабо и писать для каждого свой класс — лень, поэтому такой шаблон.

J>Как правило все Enumerator'ы в качестве контейнера используют вектор, поэтому методы этого шаблонного класса оперируют с вектором (push_back(), back() и всё такое).
J>Всё бы ничего, но есть несколько классов, которым в качестве контейнера нужен не вектор, а std::set.
J>Я сделал классы, которые наследуются от приведённого выше шаблона и переопределил нужные методы, но ошибка вылезла в методах шаблона — на тех самых push_back() и back(), мол, нет таких методов у контейнера.

J>Вопрос — как указать, что методы шаблона не должны компилироваться (специализироваться?), если есть дочерний класс, который переопределяет эти методы.

J>Как-то так.
J>Заранее спасибо.

При наследовании инстанцируется весь класс.
значит Читаем А.Александреску и пишим чтото типа политики
template < typename TInternal >
struct CVectorPolicy {
 typedef std::vector< TInternal > CContainer
 static void Push( CContainer& f_Container, const TInternal& f_Data ) {
  ......
 }
};

и такой же для std::set
далее
template <typename TExternal, typename TInternal = TExternal,
    class TBaseInterface = IEnumerator<TExternal>,
    class TBaseContainerPolicy = CVectorPolicy<TInternal> >
class CEnumeratorExt : public TBaseInterface {
 typedef typename TBaseContainerPolicy::CContainer CEnumContainer;
CEnumContainer Container;
 void Push( const TInternal& f_Enum ) {
  TBaseContainerPolicy::Push( Container, f_Enum )
 }
};


Ну вот чтото типа такого .. За ошибки при компеляции не что не скажу .. но идея такая
Соответственно выбирая политику выбираеш контейнер и методы записи в него
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.