Как вставка stl multmap уважает порядок?
У меня есть некоторые данные, которые содержат целочисленный индекс. Я постоянно создаю новые данные, которые необходимо добавить в коллекцию данных, которые у меня есть, отсортированные по этому индексу, в то же время я хочу с легкостью начать старт данных и перебирать их. Это звучит так: std:: multimap - это то, что мне нужно.
Однако мне также нужны данные с тем же индексом, которые должны храниться в том порядке, в котором он был вставлен, в этом случае означает, что когда я повторяю данные, я добираюсь до более ранних данных до более поздних данных.
Много ли это делает?
Я не нашел никаких гарантий, что это так. В руководстве sgi я не видел упоминания о том. Я попробовал это на gcc 4.3.4, и, похоже, это верно для некоторых ограниченных тестовых примеров, но, конечно, мне было интересно, требует ли стандарт этот, и я могу положиться на этот факт.
Изменить: Чтобы быть более ясным в ответ на некоторые из ответов, я хотел, чтобы сначала отсортированные данные (не уникальный), а второй - временем вставки. Я надеялся, что, возможно, вторая часть появилась бесплатно с помощью multimap, но похоже, что это не так.
Ответы
Ответ 1
Если я что-то пропустил, стандарт не предоставляет такой гарантии.
Наиболее очевидным обходным решением будет включение номера последовательности в качестве вторичного ключа. Например, в вашем классе включается статический unsigned long, и каждый раз, когда вы создаете объект для вставки в multimap, поместите его текущее значение в свой объект и увеличьте его. В функции сравнения объектов используйте этот счетчик в качестве решающего фактора для упорядочения, если данные, которые вы используете в настоящее время в качестве ключа, сравниваются равными. Обратите внимание: в этом случае каждый ключ будет уникальным, поэтому вы можете использовать карту вместо мультимапа.
Ответ 2
Кажется, новый стандарт (С++ 11) изменил это:
Порядок пар ключ-значение, чьи ключи сравниваются с эквивалентом, это порядок вставки и не изменяется. [cppreference]
Я не решаюсь использовать его, поскольку это похоже на то, что деталь легко упускается из виду при изменении стандартной библиотеки на совместимость с С++ 11, и это своего рода деталь, которая будет бесшумно вызывать ошибки, если ваша библиотека компилятора не смогла реализовать должным образом.
Ответ 3
Boost multi_index поддерживает то, что вы пытаетесь сделать, если вы не хотите использовать обходное решение, данное Джерри Коффин.
Ответ 4
Если бы я понял вас правильно, вам нужны данные, отсортированные по какому-то ключу. Всякий раз, когда вы вставляете 2 вещи с одним и тем же ключом, вам необходимо получить их в порядке вставки.
Если это так, то вам нужно взглянуть на реализацию вашего мультимапа. В зависимости от того, как он обрабатывает случай с несколькими вставками с одним и тем же ключом, он может или не может иметь эту гарантию. Я предполагаю, что стандарт не предлагает такую гарантию, поскольку это ограничило бы реализацию для особого случая.
Другой подход заключается в том, чтобы перейти к Map (не Multi) и создать составной ключ. Ключ состоит из обычного ключа, который вы выбираете, и постоянно увеличивающегося счетчика. При сравнении с равными ключами номер вставки делает ключ уникальным. Таким образом, вы вынуждаете уникальные ключи и порядок на равных "нормальных" ключах (я надеюсь, что это было понятно).
Я предполагаю, что последний подход проще всего реализовать.
Опция: (не предпочтительнее)
Вы всегда можете пойти на самодельную структуру данных с этой гарантией. Я бы выбрал Дерево (например, Red-Black или AVL) с вектором для хранения вставленных данных. На итерации вы должны найти node, перейти к вектору и перебрать его содержимое. Всякий раз, когда вы заканчиваете вектор, вы продолжаете следующий node.
Ответ 5
Нет, не будет. Если вы этого хотите, вы должны использовать "контейнер последовательности", как вектор. Вы можете загрузить вектор с помощью std:: пар, например?
Ответ 6
Похоже, что мультимап - это то, что вам нужно...
Однако мне также нужны данные с тот же индекс, который должен храниться в порядке который был вставлен, в этом случае это означает, что когда я повторяю данные, которые я получаю до более ранних данных перед более поздними данными.
Он будет в порядке индекса. Если индекс увеличивается с течением времени, когда вы вставляете больше элементов, то да из-за характера вашего индекса первые данные будут на первом месте.
В противном случае нет. Вы можете сохранить два мультифайла в одних и тех же данных. Один хранится в порядке индекса, другой - в порядке времени вставки:
std::multimap<index, T*> orderedByIndex;
std::multimap<time, T*> orderedByInsertionTime;
Предоставление вам возможности итерации карты в обоих направлениях.
( Изменить. Я читаю это, чтобы вы иногда повторяли по индексу или иногда итерации по времени вставки, но см. выше ответ, если вы имеете в виду первый индекс, а затем время вставки).
Ответ 7
Элементы, принадлежащие одному и тому же ключу, упорядочены lower_bound и upper_bound, когда вы извлекаете информацию, поэтому у вас нет гарантии, что вы получите доступ (equal_range) элементы в том порядке, в котором они были вставлены.