Долгое время Формат в PHP [закрыто]

Мне нравится ответ Маттиу, но я собираюсь пересчитать блок-схему следующим образом:

Когда НЕ использовать std :: vector

По умолчанию, если вам нужен контейнер материала, используйте std::vector. Таким образом, каждый другой контейнер является оправданным, предоставляя некоторую функциональную альтернативу std::vector.

Конструкторы

std::vector требуют, чтобы его содержимое было конструктивным, поскольку оно должно быть способный перемешать предметы вокруг. Это не страшная нагрузка на содержимое (обратите внимание, что конструкторы по умолчанию не требуются , благодаря emplace и т. Д.). Однако большинство других контейнеров не требуют какого-либо конкретного конструктора (опять же, благодаря emplace). Итак, если у вас есть объект, в котором вы абсолютно не можете реализовать конструктор перемещения, тогда вам нужно будет выбрать что-то еще.

A std::deque будет общей заменой, имеющей много свойств std::vector, но вы можете вставлять только на обоих концах deque. Вставки в середине требуют перемещения. A std::list не накладывает никаких требований на его содержимое.

Требует Bools

std::vector is ... not. Ну, это стандарт. Но в обычном смысле это не vector, так как операции, которые обычно разрешают std::vector, запрещены. И это, безусловно, не содержит bool s .

Поэтому, если вам нужно реальное поведение vector из контейнера из bool s, вы не собираетесь чтобы получить его от std::vector.

Поиск

Если вам нужно найти элементы в контейнере, а тег поиска не может быть просто индексом , вам может потребоваться отказаться от std::vector в пользу set и map. Обратите внимание на ключевое слово « может »; сортировка std::vector иногда является разумной альтернативой. Или Boost.Container's flat_set/map , который реализует сортировку std::vector.

В настоящее время существует четыре варианта их, каждый со своими собственными потребностями.

  • Используйте тег map, если тег поиска не совпадает с тем элементом, который вы ищете. В противном случае используйте set.
  • Используйте unordered, если у вас есть лот элементов в контейнере, а производительность поиска должна быть O(1), а не O(logn) ].
  • Используйте multi, если вам нужно, чтобы несколько элементов имели один и тот же тег поиска.

Заказ

Если вам нужен контейнер элементы всегда сортируются на основе конкретной операции сравнения, вы можете использовать set. Или multi_set, если вам нужно, чтобы несколько элементов имели одно и то же значение.

Или вы можете использовать отсортированный std::vector, но вам придется его сортировать.

Стабильность

Когда итераторы и ссылки являются недействительными, иногда возникает проблема. Если вам нужен список элементов, так что у вас есть итераторы / указатели на эти элементы в других местах, тогда подход std::vector к аннулированию может оказаться неприемлемым. Любая операция вставки может привести к недействительности в зависимости от текущего размера и емкости.

std::list предлагает твердую гарантию: итератор и связанные с ним ссылки / указатели становятся недействительными только тогда, когда сам элемент удаляется из контейнера , std::forward_list есть, если память является серьезной проблемой.

Если это слишком сильная гарантия, std::deque предлагает более слабую, но полезную гарантию. Недействительность получается из вставок в середине, но вставки в начале или в конце вызывают только недействительность итераторов , а не указатели / ссылки на элементы в контейнере.

Производительность вставки

std::vector обеспечивает только дешевую вставку в конце (и даже тогда она становится дорогой, если вы взорвали емкость).

std::list является дорогостоящим с точки зрения производительности (каждый вновь вставленный предмет стоит распределение памяти), но он согласован . Он также предлагает иногда незаменимую возможность перетасовки предметов вокруг практически без каких-либо затрат на производительность, а также для торговли предметами с другими контейнерами std::list одного типа без потери производительности. Если вам нужно немного перетасовать вещи вокруг , используйте std::list.

std::deque обеспечивает вставку / удаление постоянной времени по голове и хвосту, но вставка в середине может быть довольно дорогостоящим. Поэтому, если вам нужно добавить / удалить вещи как спереди, так и сзади, возможно, вам понадобится std::deque.

Следует отметить, что благодаря семантике перемещения std::vector производительность вставки может быть не так плохо, как раньше. В некоторых реализациях реализована форма перемещения семантического элемента перемещения (так называемая «swaptimization»), но теперь, когда перемещение является частью языка, оно задано стандартом.

Нет динамических распределений

std::array - это прекрасный контейнер, если вы хотите наименьшее количество динамических распределений. Это всего лишь оболочка вокруг C-массива; это означает, что его размер должен быть известен в время компиляции . Если вы можете с этим справиться, используйте std::array.

Как сказано, использование std::vector и reserve размера будет работать так же хорошо для ограниченного std::vector. Таким образом, фактический размер может меняться, и вы получаете только одно распределение памяти (если только вы не взорвали емкость).

-9
задан royhowie 8 May 2015 в 22:55
поделиться