It looks like the gcc implementation of std::list. In that case, the context is:
struct _List_impl : public _Node_Alloc_type { ... };
_List_impl _M_impl;
And you forgot to write the return type of the member function:
typedef _Alloc allocator_type;
allocator_type
get_allocator() const
{ return allocator_type(*static_cast<const _Node_Alloc_type*>(&this->_M_impl)); }
Answer for (1)
When adding a node in a list of type _Tp
, what really needs to be allocated is not an object _Tp
but a list node containing _Tp
(a _List_node<_Tp>
).
So the std::list needs to be able allocate a _List_node<_Tp>
but it has been provided an allocator for _Tp
. This is where the template typedef rebind comes in handy: it makes it possible to get an allocator for type U from an allocator for type T.
Using this rebind, we get an _Alloc<_List_node<_Tp> >
from the type _Alloc<_Tp>
.
Answer for (2) in the source file as comment:
// 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].
It is assumed that _Alloc
's type is the same as _Node_Alloc_type
as per the C++ Standard; hence the static_cast asserts the conversion is legal.