C++ for(auto i : unordered_map) 保证每次都有相同的顺序吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18301302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:52:28  来源:igfitidea点击:

Is for(auto i : unordered_map) guaranteed to have the same order every time?

c++for-loopstandardsunordered-map

提问by danijar

When I iterate over a std::unordered_mapwith the range based for loop twice, is the order guaranteed to be equal?

当我std::unordered_map使用基于范围的 for 循环迭代 a两次时,顺序是否保证相等?

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++?

这在 C++ 中是否有保证?

回答by Mike Seymour

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.

无序关联容器的迭代顺序只能在由于变异操作而重新散列时发生变化(如 C++11 23.2.5/8 中所述)。您不会在迭代之间修改容器,因此顺序不会改变。

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.

尽管规范没有明确声明不能在任何其他时间发生重新散列,但这样做会使容器上的所有迭代器无效,从而根本不可能进行任何迭代。

回答by Karthik T

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.

看起来也更好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

请注意,如果这一部分的性能很关键,你可以考虑优化串建设过程中std :: stringstream的如图所示这里,虽然它并不清楚有多少,这可能有助于