Каждый класс распределителя должен иметь интерфейс, похожий на следующий:
template<class T>
class allocator
{
...
template<class Other>
struct rebind { typedef allocator<Other> other; };
};
И классы, которые используют распределители, делают что-то лишнее:
template<class T, class Alloc = std::allocator<T> >
class vector { ... };
Но зачем это нужно?
Другими словами, разве они не могли просто сказать:
template<class T>
class allocator { ... };
template<class T, template<class> class Alloc = std::allocator>
class vector { ... };
который является более элегантным, менее избыточным и (в некоторых подобных ситуациях) потенциально безопаснее?
Почему они прошли маршрут rebind
, что также приводит к большей избыточности (т.е. Вы должны сказать T
дважды)?
(Аналогичный вопрос относится к char_traits
, а остальное... хотя они не все имеют rebind
, они все равно могут воспользоваться параметрами шаблона шаблона.)
Edit:
Но это не сработает, если вам понадобится более одного параметра шаблона!
Собственно, он работает очень хорошо!
template<unsigned int PoolSize>
struct pool
{
template<class T>
struct allocator
{
T pool[PoolSize];
...
};
};
Теперь, если vector
определяется только так:
template<class T, template<class> class Alloc>
class vector { ... };
Тогда вы могли бы просто сказать:
typedef vector<int, pool<1>::allocator> int_vector;
И это будет работать отлично, без необходимости (в избытке) сказать int
дважды.
И операция rebind
внутри vector
просто станет Alloc<Other>
вместо Alloc::template rebind<Other>::other
.