Если вы достаточно мотивированы, вы можете написать poly_any<Base>
тип.
A poly_any<Base>
- это any
, ограниченный только для хранения объектов, которые получены из Base
, и предоставляет метод .base()
, который возвращает Base&
базовому объекту.
Очень неполный набросок:
template<class Base>
struct poly_any:private std::any
{
using std::any::reset;
using std::any::has_value;
using std::any::type;
poly_any( poly_any const& ) = default;
poly_any& operator=( poly_any const& ) = default;
Base& base() { return get_base(*this); }
Base const& base() const { return const_cast<Base const&>(get_base(const_cast<poly_any&>(*this))); }
template< class ValueType,
std::enable_if_t< /* todo */, bool > =true
>
poly_any( ValueType&& value ); // todo
// TODO: sfinae on ValueType?
template< class ValueType, class... Args >
explicit poly_any( std::in_place_type_t<ValueType>, Args&&... args ); // todo
// TODO: sfinae on ValueType?
template< class ValueType, class U, class... Args >
explicit poly_any( std::in_place_type_t<ValueType>, std::initializer_list<U> il,
Args&&... args ); // todo
void swap( poly_any& other ) {
static_cast<std::any&>(*this).swap(other);
std::swap( get_base, other.get_base );
}
poly_any( poly_any&& o ); // todo
poly_any& operator=( poly_any&& o ); // todo
template<class ValueType, class...Ts>
std::decay_t<ValueType>& emplace( Ts&&... ); // todo
template<class ValueType, class U, class...Ts>
std::decay_t<ValueType>& emplace( std::initializer_list<U>, Ts&&... ); // todo
private:
using to_base = Base&(*)(std::any&);
to_base get_base = 0;
};
Тогда вам просто нужно перехватить все способы помещения материала в poly_any<Base>
и сохранить указатель на функцию get_base
:
template<class Base, class Derived>
auto any_to_base = +[](std::any& in)->Base& {
return std::any_cast<Derived&>(in);
};
Как только вы это сделаете, вы можете создать std::vector<poly_any<Base>>
, и это вектор типов значений, которые полиморфно происходят от Base
.
Обратите внимание, что std::any
обычно использует небольшую оптимизацию буфера для внутреннего хранения небольших объектов и больших объектов в куче. Но это деталь реализации.