#c #c 17
#c #c 17
Вопрос:
Я просматривал документацию для vector::vector на cppreference и в качестве упражнения пытался выяснить, как я бы реализовал explicit vector( const Allocatoramp; alloc ) noexcept;
Вопрос, который я обнаружил, задавая себе, был, почему вы передаете распределитель вектору? Это имело бы смысл только в том случае, если распределитель был полиморфным. Однако, если эта группа распределителей имеет разную информацию о состоянии, т. е. имеет разные размеры, это вызывает следующие проблемы:
- Вы не можете просто использовать распределитель в качестве члена / базового класса, поскольку это привело бы к нарезке объекта при копировании.
- Если у вас его нет в качестве элемента, его нужно было бы выделить. Распределение подразумевает, что оно может вызвать исключение.
Итак, учитывая эти причины, означает ли это, что группа распределителей должна иметь состояние только в базовом классе? Есть ли что-нибудь еще, чего мне не хватает?
Ответ №1:
Если у вас его нет в качестве элемента, его нужно было бы выделить. Распределение подразумевает, что оно может вызвать исключение.
Нет, это не обязательно должно быть выделено. Чтобы создать экземпляр std::vector
, его нужно только создать с помощью копирования.
Экземпляр распределителя передается как const
ссылка на std::vector
конструктор. std::vector
Сам по себе имеет экземпляр Allocator
в качестве (частного) члена класса, и он создается путем копирования из этого параметра.
Имейте в виду, что Allocator
это второй (по умолчанию) std::vector
параметр шаблона. Таким образом, типичная реализация объявляет Allocator
себя (частным) членом std::vector
самой себя, поэтому единственное распределение, которое происходит, — это выделение std::vector
самой себя.
Конструктор по умолчанию std::vector
default-создает свой Allocator
член класса, который также noexcept
является (начиная с C 17).
Итак, краткое содержание капсулы заключается в том, что класс распределителя (начиная с C 17) должен иметь noexcept
конструктор копирования и noexcept
конструктор по умолчанию, чтобы он соответствовал самому noexcept
требованию об исключении std::vector
.
Не требуется, чтобы дополнительное выделение выполнялось как часть построения экземпляра std::vector
(для конструкторов, которые не инициализируют содержимое std::vector
как часть его построения) — за исключением выделения std::vector
самого.