如果您足够有动力,可以编写一个poly_any<Base>
类型。
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< , bool > =true
>
poly_any( ValueType&& value );
template< class ValueType, class... Args >
explicit poly_any( std::in_place_type_t<ValueType>, Args&&... args );
template< class ValueType, class U, class... Args >
explicit poly_any( std::in_place_type_t<ValueType>, std::initializer_list<U> il,
Args&&... args );
void swap( poly_any& other ) {
static_cast<std::any&>(*this).swap(other);
std::swap( get_base, other.get_base );
}
poly_any( poly_any&& o );
poly_any& operator=( poly_any&& o );
template<class ValueType, class...Ts>
std::decay_t<ValueType>& emplace( Ts&&... );
template<class ValueType, class U, class...Ts>
std::decay_t<ValueType>& emplace( std::initializer_list<U>, Ts&&... );
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
通常使用小缓冲区优化来内部存储小对象,并将较大的对象存储在堆上。但这只是一个实现细节。
reference_wrapper
可以使用。然而,如果容器拥有这些对象并控制它们的生命周期,你必须使用智能指针如unique_ptr
-reference_wrapper
不提供任何所有权语义。 - BoBTFishstd::reference_wrapper
作为容器元素类型与普通的指针相比并没有任何优势,除了引用包装器不能为 null。 - n. m.