Is for (auto i: unordered_map) гарантированно имеет одинаковый порядок каждый раз?
Когда я перебираю по std::unordered_map
с диапазоном, основанным на цикле в два раза, гарантирован ли порядок равным?
std::unordered_map<std::string, std::string> map;
std::string query = "INSERT INTO table (";
bool first = true;
for(auto i : map)
{
if(first) first = false;
else query += ", ";
query += i.first;
}
query += ") ";
query += "VALUES (";
first = true;
for(auto i : map)
{
if(first) first = false;
else query += ", ";
query += i.second;
}
query += ");"
В приведенном выше примере результирующая строка должна быть в этой форме. Поэтому важно, чтобы оба раза, порядок итераций один и тот же.
INSERT INTO table (key1, key2, key3) VALUES (value1, value2, value3);
Гарантируется ли это на С++?
Ответы
Ответ 1
Порядок итераций неупорядоченных ассоциативных контейнеров может быть изменен только при повторном использовании в результате операции мутирования (как описано в С++ 11 23.2.5/8). Вы не изменяете контейнер между итерациями, поэтому порядок не изменится.
Хотя в спецификации явно не указано, что повторная запись не может произойти в любое другое время, это приведет к аннулированию всех итераторов по контейнеру, что делает невозможным любую итерацию.
Ответ 2
Почему бы не собрать их вместе?
for(auto i : map)
{
if(first) first = false;
else{
keys += ", ";
query += ", ";
}
keys += i.first;
values += i.second;
}
std::string query = "INSERT INTO table (" + keys + ") VALUES (" + values ")";
Выглядит лучше имо.
Обратите внимание, что если этот раздел критичен по производительности, вы можете рассмотреть возможность оптимизации процесса построения строк с помощью std:: stringstream, как показано здесь, хотя это не ясно, сколько может помочь