Это изменилось с тех пор, как C++ 11.
В C++ 03, construct
может выполнять только копирование на месте.
Обратите внимание, что в частности std::vector
- это массив объектов, но есть четкий размер и емкость. То есть может быть больше пустых элементов за пределами части массива, содержащей полезные данные.
Поэтому распределитель стандартной библиотеки имеет разделение между «строительство» и «распределение памяти». allocator
делает оба, но не в то же время. Это позволяет std::vector
выделить больше памяти, чем она использует. Когда вы добавляете новые элементы, необязательно выделять больше памяти; он может просто использовать запасную память, которую он оставил, по телефону allocator::construct
.
Также обратите внимание, что все функции C++ 03, которые добавляют элементы в std::vector
, принимают в качестве параметра элемент. push_back
, insert
, даже sized constructor takes as a value as an argument. Да, это параметр по умолчанию, но он по-прежнему принимает значение как элемент. Этот элемент скопировал в вектор, используя вызов метода construct
распределителя, который берет копию.
В C++ 11 для использования функции allocator_traits<>::construct
необходимы стандартные контейнеры. Это функция varadic, которая переводит свои параметры в фактическую конструкцию. Эта функция свойств (по умолчанию может быть специализированной) вызывает метод allocator::construct
, если этот вызов корректно сформирован. Если нет, он попытается разместить new
.
Это позволяет использовать новые функции emplace
.
Но да, объекты, содержащиеся в стандартных библиотечных контейнерах, являются фактически построенными объектами. Даже если метод распределителя construct
не вызывается.
@ Prætorian: Не могли бы вы предоставить источник этого?Код, который я только что поставил на вопрос, показывает, что он будет компилироваться в VS2010, и я считаю, что он также компилируется в gcc. – chadb
Он цитируется из стандарта C++ 11 – Praetorian
@ Prætorian: Это новое правило C++ 11 или оно было на C++ 03? – chadb