每个stl容器都将分配器作为参数:
template < class T, class Allocator = allocator<T> > class vector;
如果你自己编写类,可以使用自己的分配器。 但是可以在不使用模板的情况下编写自己的分配器吗?
例如,如果不允许使用模板
,编写此函数并不容易 pointer allocate(size_type n, const_pointer = 0) {
void* p = std::malloc(n * sizeof(T));
if (!p)
throw std::bad_alloc();
return static_cast<pointer>(p);
}
因为你怎么知道T的大小?
答案 0 :(得分:2)
好吧,如果你写的不是模板类,那么它必须只用于单一类型。只需将T
替换为您想要分配器的类型。
看起来像是一个毫无意义的练习,因为你确实有可供你使用的模板。
答案 1 :(得分:1)
如果你愿意为一个类写一个分配器,你可能......虽然它取决于你想要用它的容器。
分配器必须具有此方法:
template <class T>
class Allocator
{
public:
template <class U>
Allocator(const Allocator<U>& rhs);
};
为什么?如果你使用say,一个列表,那么你不直接为T
对象分配空间,相反,该列表将具有某种Node<T>
结构,其中包含一个或两个指向前一个/的指针下一个节点。
因此,当您传入Allocator<T>
时,它会从中构建Àllocator< Node<T> >
以进行自己的分配。
现在,如果您考虑STL容器,list
,set
和map
都有此要求。对于vector
和deque
,我甚至不确定你是否会离开,无论如何你都不会满足Allocator
概念要求。
答案 2 :(得分:-1)
std::allocator
本身就是一个模板类,所以如果要替换它,则需要使用模板类。
现在,就是说,编写一个将分配请求转发给另一个对象的分配器类非常容易:
class my_allocator
{
public:
void *allocate(size_t size) { ... }
}
template <class T>
class my_std_allocator
{
public:
pointer allocate(size_t count, const void *hint) { return static_cast<pointer>(m_my_allocator->allocate(count*sizeof(T))); }
private:
my_allocator * const m_my_allocator;
}