30

当我使用基于范围的 for 循环两次迭代 astd::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);

这在 C++ 中得到保证吗?

4

2 回答 2

35

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

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

于 2013-08-18T16:48:12.367 回答
17

为什么不把它们一起建造呢?

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 优化字符串构建过程,如下所示尽管目前尚不清楚这有多大帮助

于 2013-08-18T16:37:51.317 回答