for(auto i : unordered_map)保证每次顺序相同吗?(涉及IT技术)

34

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

在C++中是否有保证?


请告诉我你是否在某处进行了防止 SQL 注入的保护。 - D.Shawley
@D.Shawley 我现在没有。但它是关于电脑游戏的存档。我编写了这个游戏,根本没有办法从应用程序代码外部注入SQL。 - danijar
1
每当我看到使用原始字符串拼接构建 SQL 字符串时,我都会感到非常不安。 - D.Shawley
@D.Shawley 在网络请求可能导致数据库访问的情况下,这是完全可以理解的。 - danijar
5
有时候问题并不在于不可信的数据源。我曾经遇到过这样的情况,由于将玩家的名称设置为非SQL安全字符而导致应用程序崩溃。 - D.Shawley
@danijar 不管怎样都要做。你不想看到“插入大公司名称在此被黑客攻击,因为没有考虑到数据库需要 SQL 保护”的消息吧。 - noɥʇʎԀʎzɐɹƆ
2个回答

40

无序关联容器的迭代顺序只会在进行重新哈希的情况下,由于某个改变容器的操作而发生改变(如 C++11 23.2.5/8 所述)。你没有在迭代之间修改容器,因此顺序不会改变。

尽管规范并未明确说明在任何其他时候都不能重新哈希,但这样做会使所有迭代器失效,从而使任何迭代都无法进行。


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优化字符串构建过程,如此处所示,但目前仍不清楚它可能会有多大帮助


1
考虑使用 ostringstream 替代,但这是更好的方法。 - D.Shawley
@D.Shawley 如果这是一个性能密集的部分,那么可能是这样。否则,出于可读性的考虑,这可能更好,无论如何,我主要关注解决他的问题。 - Karthik T
太好了!我甚至可以缩短代码,因为第一个键和值已经给出了。std::string keys = "id", values = to_string(Id); for(auto i : serialized) keys += ", " + i.first, values += ", " + i.second; - danijar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接