Мне нужен тип варианта, который содержит экземпляры любого пользовательского класса. Поэтому я использую пустоты *:boost :: variant и void * pointers
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 проблемы, связанные с этой пустотой * в варианте:
- Копирование атрибутов с указателями на dyna физически выделенная память опасна и подвержена ошибкам.
- Пользователь может static_cast void * в WrongClass *, а не MyClass *. Он компилируется, но результат непредсказуем.
Возможные решения:
- Используйте повышение :: shared_ptr < пустота *>.
- Помните typeid для всех значений void * (если они добавлены) в
std::map<void*, typeid> typeid_map
. Когда пользователь запрашивает значение void *, отбрасывая его на любой TClass *, давайте оценим утверждение:assert(typeid_from_typeid_map == typeid(TClass*))
.
Вопросы:
1. Существуют ли другие решения для хранения значений любого пользовательского класса?
2. Может быть, вы порекомендуете лучшие решения для упомянутых проблем и укажите некоторые другие проблемы?
Да, но boost :: any не обеспечивает проверку времени компиляции и медленнее, чем boost :: variant. Поддерживает ли boost :: any обеспечить безопасность типа при литье любого значения в пользовательский класс? –
@topright Поскольку вы уже используете Boost, boost :: any похоже на способ. – karlphillip
@topright: 'boost :: any' обеспечивает проверку типа времени выполнения, а' any_cast' требует указать тип, который вы хотите получить, например. 'Myclass * c = any_cast (myMap [" myClassObj "])', который вызывает «bad_any_cast», если вы ошибались в отношении типа. Поскольку вы будете искать значения на карте, я сомневаюсь, что накладные расходы 'boost :: any' будут иметь отношение к вам. Boost any синтаксически очень чист и очень безопасен. –