std::vector<boost::variant<int,somestruct,...>> v;
v.push_back(1);
v.push_back(({1, 2, 3});
a = boost::get<int>(v[0]);
при условии, что вы знаете, какие типы должны обрабатываться при объявлении.
- редактировать
Как сказал Йоханнес, boost::variant
влияет на размер каждого элемента, но, как сказал Джеймс КанзеТем не менее, поддержание вектора смещения очень похоже на boost::any
, и я не уверен, что вы действительно можете быть более компактным.
В зависимости от ваших конкретных требований, вам может подойти другое решение.Внутренне храните разные контейнеры для каждого типа, это может быть не намного лучше, чем непосредственное использование нескольких векторов, но вы можете хранить дополнительную информацию, например, последние несколько сохраненных элементов.и у вас все еще есть все в одном месте.
Что-то вроде:
template <template <class,class> class C, typename T, typename ...Args>
struct map_ { //FIXME: return a list of type C<T1>,C<T2>...
};
template <template <class...> class C, typename ...Args>
struct fill_ { // Hack to parametrize map by Args on GCC 4.6
typedef T<Args> type;
};
template <typename... Ts>
struct hvec
{
std::map<std::string,fill_<boost::variant,map_<std::vector,Ts>> vec_map;
std::size_t last_id;
std::string last_typeid;
template <typename T>
T get(std::size_t i)
{
std::vector<T>& v = vec_map[typeid(T).name];
return vec[i];
}
template <typename T>
std::size_t push_back(const T& e)
{
std::vector<T>& v = vec_map[typeid(T).name];
v.push_back(e);
}
};
Конечно, вы можете заменить векторы на карты и, таким образом, запомнить элементы id, это будет соответствовать вашим требованиям, но добавит дополнительные затраты и все еще подразумеваетодин «адрес» / ключ за элементом.Однако в этом случае вам никогда не придется запоминать тип элемента с заданным смещением.