【发布时间】:2014-04-07 09:38:51
【问题描述】:
如果我为容器使用自定义分配器,我不喜欢重复包含的类型名:
template<typename T, size_t MyAllocatorArgument>
struct MyAllocator : public std::allocator<T>
{
// ... Usual allocator implementation
};
typedef std::vector<int, MyAllocator<int, 42>> int_container;
typedef std::vector<int, MyAllocator<long, 12>> int_container_wrong_allocator;
根据标准,第二行是未定义的行为,尽管大多数实现会将分配器rebind 分配到正确的类型。
我的问题是,鉴于容器和分配器必须为同一类型,为什么没有一些标准机制来强制执行(或完全避免)并消除用户错误的可能性?
例如,标准可以强制使用rebind(以有效地使分配器模板参数变得多余),或者可以使用如下模式,以便用户只提及一次包含的类型名:
template<size_t MyAllocatorArgument>
struct MyAllocator
{
// This would be something every allocator is required to expose.
template<typename T>
struct TypedAllocator : public std::allocator<T>
{
// This is where the normal implementation of the allocator would go.
// allocate, deallocate etc.
};
};
template<typename T, typename UntypedAllocator>
struct Container
{
// All containers would do this to get the actual allocator type they would use.
typedef typename UntypedAllocator::template TypedAllocator<T> TypedAllocator;
Container() : m_allocator(TypedAllocator()) {}
void useAllocator()
{
m_allocator.allocate();
// ... or whatever else containers need to do with allocators.
}
TypedAllocator m_allocator;
};
void allocator_test()
{
// Allocated type name isn't mentioned at point of use of container;
// only once for the container. The container does all the work.
Container<int, MyAllocator<42>> c1;
}
【问题讨论】:
-
即使使用
rebind,作者仍然可以使用模板参数为不同的客户端类型提供不同的分配器专业化。 -
@KerrekSB 问题是“鉴于容器和分配器必须为同一类型,为什么没有一些标准机制来强制执行(或完全避免)和消除用户错误的可能性?”所以你仍然可以创建一个带有分配器的vector
for double -
如果 B 派生自 A,
allocator<A>可以潜在地用于分配Bs。容器和分配器类型之间的对应关系似乎很自然,但(对我来说)很难说是否有必要.
标签: c++ stl allocator c++-standard-library