Ответ 1
Стандартная библиотека GCC всегда будет переустанавливать поставляемый распределитель, поэтому внутри он делает что-то вроде этого (в С++ 03):
typedef Alloc::template rebind<value_type>::other _Allocator_type;
(В С++ 11 он использует allocator_traits
, но в этом случае результат тот же.)
Затем вектор хранит объект этого типа внутри и использует его для выделения всех (de).
Поскольку вы не определили шаблон элемента rebind
в своем распределителе, вы только что обновили его из базового класса, результатом восстановления является std::allocator<value_type>
, а не ваш собственный тип. std::allocator
, конечно, предоставляет все эти функции, поэтому те, которые используются, независимо от того, определяете ли вы их по своему типу.
Вы можете исправить это, добавив это в свой распределитель вместо using alloc::rebind;
, чтобы vector
сохранял и использовал A
внутри:
struct A : private std::allocator<char> {
template<typename U>
struct rebind {
typedef A other;
};
N.B. это будет работать только для vector
, потому что vector
не нужно строго переустанавливать распределитель (пользователям требуется создать экземпляр шаблона с помощью allocator<value_type>
, но GCC vector
все равно перепроверяет, так что если пользователь создает экземпляр vector<int, std::allocator<char>>
он по-прежнему работает.) Для контейнеров на основе node, таких как std::set
, ваш распределитель должен быть шаблоном, который можно отскочить, потому что контейнеру необходимо выделять его внутренние типы node, а не value_type
, поэтому ему нужно Alloc::rebind<internal_node_type>::other
.