提供STL容器(例如,std :: vector)与分配器作为模板参数之间的区别是什么,例如:
std::vector<int, std::allocator<int>> some_ints;
并提供一个分配器作为构造函数参数,例如:
std::allocator<int> temp;
std::vector<int> some_ints(temp);
鉴于它们不是同一个东西(即一个提供类型,另一个是类型实例)并且可以彼此分开使用,那么两者的优点是什么?
解决方法:
可以分开使用吗?
模板参数只提供类型.你还需要一个实例.这是不可分割的.
这就像拥有一个功能模板< typename Type> f(类型实例);并询问Type和instance之间的区别是什么,它们可以单独使用,还有哪些优点.如果您了解什么是模板,类型和实例/对象,那就没有多大意义.
(为了简单起见,它是c 11)
这里有vector的类型模板:
template<
class T,
class Allocator = std::allocator<T>
> class vector;
这是默认的构造函数:
explicit vector( const Allocator& alloc = Allocator() );
总是有一个Allocator实例作为alloc参数提供.在这方面,所有其他调用都是类似的.默认情况下,它是默认构造的新Allocator对象.因此,从语义上讲,每当您不使用向量指定allocator参数的向量调用时,您就会创建新的Allocator对象(在默认情况下,它很可能什么也不做,但程序的逻辑流程如上所述).
你不能传递一些不适合Allocator的东西,因为你会遇到类型不匹配,或者在这种情况下恰好是替换失败.
在不触及向量定义的情况下,您可以做的一个非常非标准是定义DerivedAllocator,它派生自Allocator实例化它并作为参数传递.例如:
vector<T> v( DerivedAllocator<T>() );
但是,我无法在我的头顶上提出这种结构的用例.有一个很好的用例,请参阅下面的附录.
什么是Allocator模板参数有用?
在某些系统中,您有多种类型的内存,因此提供单独的分配器(主要是单独的分配器类型)可能很有用.例如:SRamAllocator,RamAllocator等.
这在嵌入式系统中非常常见.我知道那里有一个实现中的内存模型实际上并不是免费的,当你释放它时它就是一个丢失的块.它本质上是一个移动指针.理由是它非常快,因为它没有任何逻辑来跟踪由释放引起的“漏洞”块.您不希望使用具有大量新/删除模式的方案.
什么是allocator构造函数参数有用?
在有状态分配器的情况下它是有意义的.想象一下,你想拥有两个相同类型的存储.例如.跟踪一些内存使用情况,或者你带来多少逻辑“内存库”的原因.您可能希望为程序中的每个线程创建一个分配器,因此更容易维护正确的CPU /内存亲和性.
创建新对象时,需要告知哪些分配器实例应该处理它.
您可以在技术上为每个实例使用不同的类型实现所有内容,但这会降低可能的运行时动态的可用性.
注意:默认分配器和pre-c 11自定义分配器不允许具有状态,因此它们基本上以完全静态的方式实现.它实际上与您使用的Allocator实例无关.这就是默认的Allocator()有效的原因.
因此,理论上人们不需要实例化它们,并且可以只使用类型和静态接口……如果标准这样说的话.但故意不允许这种方式允许具有内部状态的分配器类型(这句话是个人意见).
重要补充:我错过了c’tor参数分配器的一个重要特权,这很可能是存在的理由.多态分配器.这里详细描述:polymorphic_allocator: when and why should I use it?
基本上,使用不同的Allocator类型会改变对象的整个类型,因此一端基本上是相同的对象,只有分配器才有区别.这在某些情况下是非常不受欢迎的.为了避免这种情况,可以编写多态分配器并在类型中使用基本分配器,并将具体实现用作运行时参数.因此,可以使用不同的存储引擎具有完全相同类型的对象.因此,使用参数会产生一些开销,但它会将分配器的状态从铁质标记到类型上,从而减少实现细节.