Приведите набор указателей к базовому классу на набор указателей на его шаблонный производный класс - PullRequest
0 голосов
/ 12 октября 2018

Я хочу хранить элементы в какой-либо пользовательской базе данных в памяти, классифицированной по их типу.

Для этого я хочу использовать карту, ключ которой - это type_index сохраняемого значения,и значение которого является std :: set шаблонного дочернего класса, который хранит сохраняемое значение.Это может быть проще проиллюстрировать, чем объяснить:

Мой базовый класс называется ItemBase.

Дочерний класс выглядит так:

template<class T>
class Item : public ItemBase {

    // ...
    T stored_item;  
    // ...

};

И мой class Database имеет следующее:

typedef std::set<ItemBase*> ItemList;

template <typename T>
using DefinedItemList = std::set<Item<T>*>;

typedef std::unordered_map<std::type_index, ItemList> MapOfItemLists;

// ...

MapOfItemLists itemsByType;

При сохранении элемента я сохраняю его с этой функцией:

template<typename T> Item<T>* Database::add_item(T item) {

    Item<T>* pItem = new Item<T>(item,this);

    if(!item_type_exists(typeid(T)))
        itemsByType[typeid(T)] = ItemList();

    itemsByType[typeid(T)].insert(pItem);

    return pItem;
}

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

Поскольку объекты могут принимать любой тип, я не могу заранее определить типы, поэтому я сохраняю их в наборах ItemBase*.Но как восстановить наборы Item<T>*?

Я пытался выполнить приведение типа этого:

ItemList ret = itemsByType.find(type_index)->second;
return dynamic_cast<DefinedItemList<T>&>(ret);

Но это дало мне эту ошибку:

 error: cannot dynamic_cast ‘ret’ (of type ‘ItemList {aka class std::set<ItemBase*>}’) to type ‘DefinedItemList<int>& {aka class std::set<Item<int>*, std::less<Item<int>*>, std::allocator<Item<int>*> >&}’ (source type is not polymorphic)

Но если я не ошибаюсь, ItemBase полиморфен:

class ItemBase {
public:
    virtual ~ItemBase() = 0;

};
inline ItemBase::~ItemBase() {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...