Итак, у меня есть один шаблонный класс, B
, который наследуется от не шаблонного класса A
, Теперь эта шаблонная версия B
, имеет набор из четырех допустимых и известных шаблонных классов, вызывает их B<uint8_t>, B<uint16_t>, B<uint32_t>, B<uint64_t>
,
В настоящее время я храню их на карте, boost::unordered_map<std::string, A>
и я хотел бы создать какой-то способ приведения к разным типам. Я могу легко дифференцировать на основе A::width()
метод, который возвращает 8, 16, 32 или 64 соответственно.
Я ломал голову над хорошим дизайном, но я не могу придумать, как найти лучшее решение, чем каждый раз использовать себя.
Вот минимальный рабочий случай:
class A {
std::size_t width() const = 0;
};
template <typename value> class B : public A {
std::size_t width() const {
return sizeof(value) * 8;
}
};
В пределах использования:
boost::unordered_map<std::string, A *> _bmap;
template <class T> T cast_A(A * const a) {
switch (a->width()) {
case 8: return dynamic_cast<B<uint8_t> *>(a);
// removed for brevity
}
Проблема в том, что он заставляет пользователя проверять тип времени выполнения A
класс после того, как сделать метод приведения абсолютно бесполезным.
Я приветствую любой вклад. 🙂
Вы можете использовать, например, шаблонный get()
метод, который преобразует в запрашиваемый размер через virtual
метод, проходящий через самый большой поддерживаемый тип. Если преобразование потеряет биты (проверено во время выполнения), вы можете выдать ошибку.
Я думаю, что уныние в этом случае не очень хорошая идея. Кажется, это проблема дизайна.
Тем не менее, вы можете попробовать реализовать что-то вроде шаблон посетителя для этих классов. Это может решить вашу проблему, но я не уверен, потому что нет примеров использования объектов B.