c как правильно вызвать освобождение в пользовательском контейнере

#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 🙂