Я посмотрел cppreference.com и нашел это
vector();
explicit vector( const Allocator& alloc );
почему бы просто не
explicit vector(const Allocator& alloc = Allocator());
1 конструктор вместо 2.
Для этого есть причина? то же самое с resize(std::size_t,const T& t)
и
resize(std::size_t)
почему бы просто не resize(std::size_t,const T& t = T())
поэтому я подумал об этом, и для метода изменения размера, вероятно, нужно разрешить создание указателя на функцию-член с одним аргументом, а для конструктора я не знаю.
explicit vector(const Allocator& alloc = Allocator());
потребует, чтобы Allocator
был конструируемым по умолчанию и копируемым. Если Allocator
не может выполнить одно из этих действий, вы не сможете создать vector
по умолчанию.
но требования к распределителю в любом случае требуют, чтобы распределитель имел конструктор копирования
@user24551355 user24551355 конструктор копирования, да. Но не конструктор по умолчанию
если у вас нет конструктора по умолчанию для распределителя, вы даже не можете вызвать конструктор по умолчанию std::vector, так какой у вас пионт? std::vector default condtructor также вызовет конструктор по умолчанию для своего распределителя
@user24551355 user24551355 тип Allocator
тоже является параметром шаблона, и я уверен, что по умолчанию есть конструктор по умолчанию. Но вы правы: если бы вы использовали собственный тип Allocator
, для использования первой формы конструктора потребовался бы конструктор по умолчанию.
Вот почему существует мощный комитет по C++, который занимается стандартизацией, это сложно.
@MarkRansom C++ — тяжелый человек. Есть так много странных решений.
@MarkRansom распределитель по умолчанию std::allocator
имеет конструктор по умолчанию и конструктор копирования, но другие классы распределителя ДОЛЖНЫ иметь конструктор копирования, это требование распределителя
Чтобы внести ясность: vector()
уже требует, чтобы Allocator
был конструируемым по умолчанию. Использование двух конструкторов вместо одного не дает никаких преимуществ в этом отношении.
Если бы конструктор по умолчанию был явным, поскольку это была просто версия с одним аргументом и значением по умолчанию, вы не могли бы инициализировать вектор с помощью {}
. Для resize
потребуется, чтобы тип элемента был копируемым, а не просто инициализировал значения (технически вставляя значения) новых элементов.
Что касается std::vector<T, Allocator>:
Что касается первого вопроса, то это вопрос полезности и эффективности.
Для вектора() без аргумента:
vector();
Объект распределителя предоставляется шаблоном, по умолчанию используется std::allocator.
Определение можно записать так:
constexpr vector() : elem(nullptr), array_size(0), space(0) {}
Для вектора с объектом распределителя, предоставленным в качестве аргумента:
constexpr explicit vector(const Allocator& alloc) noexcept;
Определение можно записать так:
constexpr explicit vector(const Allocator& alloc) noexcept : elem(nullptr), array_size(0), space(0), v_alloc(alloc) {}
Оба создадут пустой вектор. Если «Allocator» является пользовательским распределителем, т. е. «my_allocator», присвоение объекта через аргумент позволяет использовать характеристики, отличные от характеристик объекта распределителя, предоставленного шаблоном. Если объект распределителя предоставляется по шаблону, все значения внутри объекта имеют значения по умолчанию. Если объект распределителя предоставляется в качестве аргумента, распределитель можно перенастроить перед передачей объекта в качестве аргумента.
Когда вектор создается без аргумента, распределитель создается по умолчанию. Когда вектор создается с аргументом, сначала создается распределитель по умолчанию, а затем копируется из аргумента. Поэтому было бы менее эффективно иметь один конструктор с аргументом, который по умолчанию имеет значение «(const Allocator& alloc = Allocator())».
Что касается второго вопроса, это вопрос эффективности.
«void resize(std::size_t count)» добавляет элементы по умолчанию, когда размер вектора увеличивается. Каждый добавляемый элемент по умолчанию создается с помощью std::allocator_traits:
std::allocator_traits<decltype(v_alloc)>::construct(v_alloc, ptr);
«void resize(std::size_t count, const T& value)» добавляет элементы «value» с помощью конструктора копирования, когда размер вектора увеличивается.
std::allocator_traits<decltype(v_alloc)>::construct(v_alloc, ptr, value)
Если «T()» было указано по умолчанию для «value», добавленные элементы создаются копией, а не конструируются по умолчанию.
Ответы на эти две функции на самом деле совершенно разные. Может, спрашивать по одному?