没有模板的分配器

时间:2010-05-06 17:38:05

标签: c++ templates memory-management

每个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的大小?

3 个答案:

答案 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容器,listsetmap都有此要求。对于vectordeque,我甚至不确定你是否会离开,无论如何你都不会满足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;

}