распределитель без шаблона - PullRequest
2 голосов
/ 06 мая 2010

Каждый контейнер 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);
  }

Потому что как ты узнал размер Т?

Ответы [ 3 ]

2 голосов
/ 06 мая 2010

Ну, если бы вы написали тот, который не был классом шаблона, он должен был бы быть только для одного типа. Просто замените T на тот тип, для которого вы хотите использовать распределитель.

Похоже на бессмысленное упражнение, поскольку у вас действительно есть шаблоны, доступные для использования.

1 голос
/ 06 мая 2010

Если бы вы хотели написать распределитель для одного класса, вы, вероятно, могли бы ... хотя это зависело бы от контейнера, для которого вы хотите его использовать.

Распределитель должен иметь этот метод:

template <class T>
class Allocator
{
public:
  template <class U>
  Allocator(const Allocator<U>& rhs);
};

Почему? Если вы используете, скажем, список, то вы напрямую не выделяете пространство для объекта T, скорее, список будет иметь какую-то структуру Node<T>, которая содержит один или два указателя на предыдущий / следующий узлы.

Поэтому, когда вы передаете Allocator<T>, он будет строить Àllocator< Node<T> > из него, чтобы делать свои собственные распределения.

Теперь, если вы подумаете о контейнерах STL, list, set и map имеют это требование. Я даже не уверен, что вы обойдетесь без vector и deque, и в любом случае вы не будете соответствовать требованиям Allocator концепции.

0 голосов
/ 06 мая 2010

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;

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...