Boost :: Вариант и Void * указатели - PullRequest
2 голосов
/ 07 февраля 2011

Мне нужен тип варианта, который содержит экземпляры любого определенного пользователем класса.Поэтому я использую void *:

typedef boost::variant<void*, int, float, std::string> Tvariant;

Я создал класс-оболочку с картой:

typedef std::map<std::string, Tvariant> Tvalues;

Пример использования:

int x = 123;
attributes.set("int_var", x);
x = attributes.get<int>("int_var");

MyClass* obj = new MyClass();
attributes.set("void*_var", obj);
obj = static_cast<MyClass*>( attributes.get<void*>("void*_var") );
obj = attributes.cast<MyClass*>("void*_var"); // the same

Есть2 проблемы с этим void * в классе вариантов:

  1. Копирование атрибутов с указателями в динамически выделенную память опасно и подвержено ошибкам.
  2. Пользователь может static_cast void * в WrongClass *, но нев MyClass *.Он компилируется, но результат непредсказуем.

Возможные решения:

  1. Используйте boost :: shared_ptr .
  2. Запомните typeid для всех void* значения (при их добавлении) в std::map<void*, typeid> typeid_map.Когда пользователь запрашивает значение void *, приведя его к любому TClass *, давайте оценим утверждение: assert(typeid_from_typeid_map == typeid(TClass*)).

Вопросы :
1. ЕстьЕсть ли другие решения для хранения значений любого пользовательского класса?
2. Может быть, вы порекомендуете лучшие решения для упомянутых проблем и укажете на некоторые другие проблемы?

1 Ответ

6 голосов
/ 07 февраля 2011

Вы смотрели на Boost :: Any ? Это то, что несет с собой знание времени компиляции приведения типа, скрывая, какой это тип на самом деле через Any.

...