Is for(auto i : unordered_map) guaranteed to have the same order every time?
Solution 1
The iteration order of unordered associative containers can only change when rehashing as a result of a mutating operation (as described in C++11 23.2.5/8). You are not modifying the container between iterations, so the order will not change.
Although the specification doesn't explicitly state that rehashing can't occur at any other time, doing so would invalidate all iterators over the container, making any iteration at all impossible.
Solution 2
Why not build them together?
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 ")";
Looks nicer too imo.
Please note, if this section is performance critical, you could consider optimizing the string building process with std::stringstream as shown here, though it is not clear how much that might help
danijar
Researcher aiming to build intelligent machines based on concepts of the human brain. Website · Twitter · Scholar · Github
Updated on August 19, 2020Comments
-
danijar over 3 years
When I iterate over a
std::unordered_map
with the range based for loop twice, is the order guaranteed to be equal?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 += ");"
In the example above, the resulting string should be in that form. Therefore, it is important that both times, the order of iteration is the same.
INSERT INTO table (key1, key2, key3) VALUES (value1, value2, value3);
Is this guaranteed in C++?
-
michelson over 10 yearsConsider using
ostringstream
instead, but this is the better approach. -
Karthik T over 10 years@D.Shawley yes probably if this is a performance intensive section. Else this might be better purely on readability grounds, either way I was mainly focusing on the fix to his problem.
-
danijar over 10 yearsGreat! I could even cut that down, because the first key and value is given.
std::string keys = "id", values = to_string(Id); for(auto i : serialized) keys += ", " + i.first, values += ", " + i.second;
.