2013-07-06 4 views
4

У меня есть кэш неоднородных объектов, хранящихся по имени. Обратите внимание, что для них нет общего базового класса. В момент создания я также должен хранить объект DeleteR (так как я знаю тип в то время), так что карта выглядит следующим образом:C++ - 11 для карты гетерогенных объектов

map<string, pair<void *, Deleter> > data; 

когда объект извлекается (с помощью шаблонного метода), это верните требуемый тип. Деструктор для кеша просто вызывает Deleter и удаляет пару с карты. Все это работает.

Было бы хорошо, однако, если C++ 11 позволит мне сделать что-то вроде:

map<string, unique_ptr_base> data; 

где unique_ptr_base бы (мнимая) базовый класс всех unique_ptr и его виртуальный деструктор удалить предмет. Тогда я мог бы просто удалить элемент с карты и не беспокоиться об освобождении.

Написание специального класса для этой цели не слишком сложно, но в данном случае это не оправдано, так как нынешний способ занимает только одну линию, и не так много опасностей утечки указателя. Итак, есть ли какая-то особенность нового стандарта, который я пропускаю, или я должен просто оставить его как есть?

+1

«У меня есть кэш разнородных объектов» Не делай этого. Либо иметь кэш для каждого типа объекта, либо создать интерфейс. Обратите внимание, что интерфейс не обязательно должен быть унаследован объектами напрямую. –

+0

Это библиотека, поэтому я не могу контролировать, какой тип пользователь может захотеть использовать. И хотя, возможно, я могу создать отдельный кеш для каждого типа, но тогда у меня будет карта для хранения всех кешей, которые являются гетерогенной картой :) – user2557021

+1

Если это абсолютно необходимо, используйте 'boost :: any'. –

ответ

4

Если у вас нет с сохранением состояния удаливших, вы можете в значительной степени использовать:

std::unique_ptr<void, void (*)(void *)> 

Например:

using any_ptr = std::unique_ptr<void, void (*)(void *)>; 

any_ptr p(static_cast<void *>(std::fopen("/dev/null")), 
      [](void * x) { std::fclose(static_cast<FILE*>(x)); }); 
+0

Итак, если мой Create делает это: 'template Create (const string & s) {data.insert (make_pair (s, make_pair (новый T, Deleter ())))}' - как бы он выглядел сейчас? – user2557021

+0

@ user2557021: Что-то вроде 'data [s] = any_ptr (новый T, [] (void * p) {Deleter () (static_cast (p));})' Я полагаю. –

+0

ОК, я получил его сейчас, спасибо большое! – user2557021

Смежные вопросы