Привет.
Есть шаблонный класс, который описывает 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(), мол, нет таких методов у контейнера.
Вопрос — как указать, что методы шаблона не должны компилироваться (специализироваться?), если есть дочерний класс, который переопределяет эти методы.
Как-то так.
Заранее спасибо.
Здравствуйте, 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 )
}
};
Ну вот чтото типа такого .. За ошибки при компеляции не что не скажу .. но идея такая
Соответственно выбирая политику выбираеш контейнер и методы записи в него