web-dev-qa-db-ja.com

for(auto i:unordered_map)は常に同じ順序になることが保証されていますか?

std::unordered_map範囲ベースのforループを2回使用すると、順序が等しいことが保証されますか?

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++で保証されますか?

21
danijar

順不同の連想コンテナの反復順序は、(C++ 11 23.2.5/8で説明されているように)変換操作の結果として再ハッシュする場合にのみ変更できます。反復間でコンテナを変更しないため、順序は変更されません。

仕様では、リハッシュは他のどの時点でも発生しないと明記されていませんが、これを行うと、コンテナに対するすべてのイテレータが無効になり、反復がまったく不可能になります。

28
Mike Seymour

それらを一緒に構築してみませんか?

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を使用して文字列構築プロセスを最適化することを検討してください ここ ですが どれだけ役立つかは不明です =

17
Karthik T