Похоже, что gcc-реализация std :: list. В этом случае контекст таков:
struct _List_impl : public _Node_Alloc_type { ... };
_List_impl _M_impl;
И вы забыли написать тип возвращаемого значения функции-члена:
typedef _Alloc allocator_type;
allocator_type
get_allocator() const
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); }
Ответ за (1)
При добавлении узла в список типа _Tp
на самом деле нужно выделить не объект _Tp
, а узел списка, содержащий _Tp
(a _List_node<_Tp>
).
Таким образом, std :: list должен иметь возможность выделять _List_node<_Tp>
, но ему был предоставлен распределитель для _Tp
. Вот где шаблон typedef rebind пригодится: он позволяет получить распределитель для типа U от распределителя для типа T.
Используя эту привязку, мы получаем _Alloc<_List_node<_Tp> >
от типа _Alloc<_Tp>
.
Ответ (2) в исходном файле в качестве комментария:
// NOTA BENE
// The stored instance is not actually of "allocator_type"'s
// type. Instead we rebind the type to
// Allocator<List_node<Tp>>, which according to [20.1.5]/4
// should probably be the same. List_node<Tp> is not the same
// size as Tp (it's two pointers larger), and specializations on
// Tp may go unused because List_node<Tp> is being bound
// instead.
//
// We put this to the test in the constructors and in
// get_allocator, where we use conversions between
// allocator_type and _Node_Alloc_type. The conversion is
// required by table 32 in [20.1.5].
Предполагается, что тип _Alloc
совпадает с _Node_Alloc_type
в соответствии со стандартом C ++; следовательно static_cast утверждает, что преобразование допустимо.