Ответ
Нет. std::unordered_map — это хэш-таблица, и порядок её элементов не гарантируется. Он зависит от хэш-функции, внутренней структуры бакетов (корзин) и может меняться при рехэшировании (например, при увеличении размера контейнера).
Пример:
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
std::unordered_map<int, std::string> map;
// Вставка в порядке возрастания ключа
map.insert({3, "three"});
map.insert({1, "one"});
map.insert({4, "four"});
map.insert({2, "two"});
std::cout << "Iteration order:n";
for (const auto& [key, value] : map) {
std::cout << key << ": " << value << 'n';
}
// Вывод может быть, например: 2: two, 4: four, 1: one, 3: three
// Порядок не соответствует ни порядку добавления, ни сортировке по ключу.
}
Альтернативы, если порядок важен:
std::map— хранит элементы, отсортированные по ключу (логарифмический доступ).std::vector<std::pair<Key, Value>>— сохраняет порядок вставки, но поиск линейный.- Комбинация структур — например,
std::unordered_map<Key, Value>для быстрого поиска +std::vector<Key>для сохранения порядка.
Ответ 18+ 🔞
А, ну это же классика, ёпта! Смотри, тут всё просто, как два пальца об асфальт. std::unordered_map — это по сути своей обычная хэш-таблица, хитрая жопа, которая хранит данные как бог на душу положит. Порядок элементов там — это пиздец полный, никаких гарантий тебе не светит.
Представь, ты закидываешь в неё ключи по порядку: один, два, три. А когда начинаешь перебирать, она тебе может выдать: три, один, два. Или вообще: два, три, один. Всё зависит от её внутренней кухни — от хэш-функции, от того, как она там бакеты раскладывает. А если она ещё и рехэшируется (ну, когда места мало становится), так там вообще волнение ебать — порядок может враз поменяться.
Вот, глянь, наглядный пример:
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
std::unordered_map<int, std::string> map;
// Кидаем по порядку, с тройки на двойку
map.insert({3, "three"});
map.insert({1, "one"});
map.insert({4, "four"});
map.insert({2, "two"});
std::cout << "А теперь смотрим, в каком порядке она нам отдаст:n";
for (const auto& [key, value] : map) {
std::cout << key << ": " << value << 'n';
}
// И тут может вылезти что угодно! Например: 2: two, 4: four, 1: one, 3: three
// Никакой логики, ни по ключу, ни по вставке. Полный пиздец.
}
Так что же делать, если порядок всё-таки нужен? Ну, варианты есть, конечно.
std::map— вот это уже серьёзный парень. Он хранит всё отсортированным по ключу, всегда аккуратно. Но за красоту платишь скоростью — доступ там логарифмический, не мгновенный.std::vector<std::pair<Key, Value>>— самый простой и честный способ. Всё лежит ровно в том порядке, в каком ты засунул. Но искать в этой куче — это отдельный вид спорта, линейный поиск, овердохуища времени уйдёт.- Сделать велосипед — то есть взять две структуры. Одна (
std::unordered_map) для быстрого поиска по ключу, а вторая (например,std::vector) — чтобы просто запоминать, в каком порядке ты эти ключи добавлял. Ну, или взять готовую библиотеку, где это уже сделано. В общем, если нужен порядок —unordered_mapтебе не друг, это точно.