почему контейнеры STL используют копирование для заполнения при изменении размера? - PullRequest
1 голос
/ 19 августа 2010

все контейнеры STL, которые реализуют resize, используют копии для заполнения новых элементов, даже если источником копии является созданный по умолчанию объект?

Почему так сделано?

Я не вижу никаких преимуществ и некоторых затрат.


В качестве контекста я наткнулся на это, когда искал контейнер произвольного доступа для элементов, которые нельзя скопировать :

Ответы [ 4 ]

3 голосов
/ 19 августа 2010

Это экономит на сложности. Нам, безусловно, нужен случай конструирования копии, и конструкцию по умолчанию можно смоделировать как репликацию созданного по умолчанию объекта.

Наказание за производительность незначительно. Запись нулей примерно такая же скорость, как копирование нулей. Нарушение совместимости равно нулю, поскольку все контейнеры все равно требуют копирования. Конструкция по умолчанию с другой стороны не требуется.

Если вы действительно хотите использовать стандартные контейнеры с не копируемыми объектами, посмотрите на C ++ 0x и конструкцию на месте с emplace. Однако нет способа emplace нескольких элементов одновременно. (Если вы используете deque, цикл emplace не должен сильно снижать производительность по сравнению с resize.)

1 голос
/ 19 августа 2010

В вашем случае, возможно, вам лучше хранить указатели на эти объекты в контейнере - указатель можно скопировать.

По поводу копирования в контейнер; какая альтернатива? Если вам нужно было перераспределить новый блок памяти для хранения того, что хранится, вы должны каким-то образом перенести туда существующие данные!

0 голосов
/ 19 августа 2010

Стандартные контейнеры определяют требования CopyConstructible и Assignable для типа значения, и эти требования достаточны для поддержки всех операций над контейнерами и последовательностями (вы также можете захотеть, чтобы они были сопоставимы для ассоциативных контейнеров, но даже это не требуется.поскольку вместо этого вы можете предоставить компаратор).

То, что вы запрашиваете, - это иметь один набор требований для набора операций, состоящего из части Контейнера плюс кое-что из Последовательности (а именно 1-параметр resize() для тех контейнеров, которые никогда не перемещают свое содержимое, operator[], clear() и интерфейс итератора, исключая *it = t), и другой набор требований для остальных.Стандартные библиотеки предпочитают делать это наоборот: выбрать общий набор требований, которые охватывают почти все, а затем предъявляют дополнительные требования для небольших функциональных возможностей (например, требование быть конструируемым по умолчанию для вызова resize() безуказание второго параметра).

Контейнеры просто не были задуманы с учетом вашего конкретного набора операций - копирование и присвоение являются неотъемлемой частью того, для чего они предназначены, то есть для хранения значений, которые помещаются вих, так что я полагаю, что, по мнению Степанова, это не «маленький функционал».Таким образом, существуют более широкие требования, поскольку контейнер абстракции больше, чем предложенный вами объект ResizeableCollectionOfDefaultConstructedObjects.Фактически, уберите resize(), и CollectionOfDefaultConstructedObjects - это всего лишь массив.Я полагаю, что разработчики стандартов STL и C ++ не сталкивались с вашим вариантом использования достаточно часто, чтобы считать его заслуживающим абстракции.

0 голосов
/ 19 августа 2010

Единственная причина, по которой я могу думать об этом, заключается в том, что контейнеры поддерживают вставку, и для вставки требуется копия.Вы должны быть в состоянии создать контейнер, который поддерживает изменение размера способом, подобным deque (с постраничным и несмежным), который по умолчанию создает новые элементы.Однако вам придется запретить назначение всего контейнера вместе со вставкой элементов - вместо этого вы можете изменить объекты, созданные в коллекции.

Я предполагаю, что никто не видел необходимости в коллекции, которая не поддерживаетвставка и не реализует копирование типа значения.В качестве еще одного примечания, вы, вероятно, должны пометить это как вики, прежде чем оно закроется;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...