#c #containers #allocator
#c #контейнеры #распределитель
Вопрос:
Я создал пользовательский класс контейнера, который выглядит следующим образом:
template <typename T, typename Alloc=std::allocator<T>>
class container {
...
};
Для выделения памяти я использую std::allocator_traits<Alloc>::allocate(some_size)
.
Я думаю, я мог бы также просто использовать Alloc::allocate(some_size)
.
Проблема возникает, когда я хочу освободить память с std::allocator_traits<Alloc>::deallocate(...)
помощью или Alloc::deallocate(...)
, потому deallocate
что вызываемый с std::allocator_traits
помощью не является статическим и требует передачи объекта распределителя.
Alloc::deallocate
будет работать, потому что он статичен.
В чем разница между этими двумя типами вызова функций распределителя и почему std::alloctor_traits<Alloc>::deallocate(...)
они больше не являются статическими?
Немного моего реального кода:
template <typename T, typename Alloc>
ring<T, Alloc>::~ring() {
if (__n_items > 0) {
for(reference item : *this) {
item.~value_type();
}
std::allocator_traits<Alloc>::deallocate(__buffer, __size);
}
}
Слишком мало аргументов приводит к отсутствию экземпляра распределителя.
Ответ №1:
Для обоих методов allocate
и deallocate
allocator_traits
требуется объект распределителя. Стандартным библиотечным контейнерам предоставляется экземпляр распределителя для хранения и использования (обычно пользователи полагаются на поведение конструктора по умолчанию, который по умолчанию создает такой распределитель). Если вы планируете использовать свой класс контейнера с распределителем с сохранением состояния, вам следует сделать то же самое; если ваш пользовательский распределитель не имеет состояния для каждого экземпляра, вы можете просто создать его по умолчанию по мере необходимости.
Комментарии:
1. Большое вам спасибо, я пропустил эту часть в std::containers 🙂