Необходимо сделать базовую реализацию boost::any
.
Главное условие: чтобы можно было свободно хранить в контейнерах разные типы.
Требуется такое поведение:
MyAny a = 5;
cout << a.get() << endl; // a.get() -> int
a = "sdfsdf"; // Нельзя!!!
std::vector<MyAny> vec;
MyAny b = 5;
MyAny c = "sdfsdf";
MyAny d = MyClass(1, 4);
vec.push_back(b);
vec.push_back(c);
vec.push_back(d);
Подскажите, где посмотреть как реализовать подобный функционал.
Если в двух словах, то идея такая. Any
будет хранить в себе указатель на объект, который хранит в себе то, что вы хотите положить в Any
. Чтобы безопасно извлекать данные будет использоваться понижающее приведение типа dynamic_cast
.
Для начала опишем небольшую иерархию "хранителей" данных:
class IValue{
public:
virtual ~IValue(){}
};
template<class T>
class Value : public IValue{
T _value;
public:
explicit Value(const T &value):
_value(value)
{}
const T& get() const{
return _value;
}
};
Тут все просто. Базовый класс IValue
, от него наследуется шаблон Value
, в котором можно хранить объект любого типа(кроме тех, которые не поддерживают операцию копирования).
Теперь как будет выглядеть минималистичная реализация Any
:
class Any{
std::unique_ptr<IValue> _value;
public:
template<class T>
Any(const T &value):
_value(new Value<T>(value))
{}
template<class T>
T get() const{
Value<T> *value = dynamic_cast<Value<T>*>(_value.get());
if(!value){
return T ();
}
return value->get();
}
};
Any
хранит указатель типа IValue
. Когда мы пытаемся прочитать записанные данные, выполняется понижающее приведение типа:
Value<T> *value = dynamic_cast<Value<T>*>(_value.get());
Если dynamic_cast
вернет 0
, значит мы пытаемся извлечь неправильный тип.
Вам, для ваших целей, нужно еще реализовать копирующий конструктор и оператор присваивания, в которых будет выполняться глубокое копирование.
Полный пример
PS: Кстати, в a = "sdfsdf";
нет ничего криминального. По-моему, куда более естественно выглядит реализация в которой так делать можно. Вам придется приложить дополнительные усилия, чтоб реализовать такое ограничение.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Столкнулся с ошибкой после выполнения команды make install в окружении cygwin при установке библиотеки:
Есть QTableView, соединенная с QSqlTableModel, у это таблицы также есть делегаты и прокси модельВозможно ли вывести данную таблицу на печать с сохранением...
Необходимо собрать проект под систему на 32bit arm из системы x86_64 (надеюсь, в определениях не напутал, на интеловский x64 процессор, на целевой...