c++ - 将自己的大小插入到 std::map
问题描述
我刚刚在我的代码(C++14)中遇到了一个奇怪的错误,这是由 std::map 的意外(至少对我而言)行为引起的。这是一个演示该行为的简单示例:
#include <iostream>
#include <map>
int main()
{
std::map<int, int> m;
for(int i = 0; i < 3; ++i) {
m[m.size()] = m.size();
}
for(const std::pair<int, int>& e : m) {
std::cout << e.first << " " << e.second << std::endl;
}
return 0;
}
这打印:
0 1
1 2
2 3
我期待:
0 0
1 1
2 2
这里发生了什么?地图首先使用 set 添加一个新元素,first
然后(当地图的大小已经增加时)设置second
?我不太明白为什么这会有意义。还是有其他解释?谢谢!
解决方案
表达式中发生了一些事情
m[m.size()] = m.size();
首先,m[m.size()]
需要= m.size()
评估。在 C++14 中,评估顺序是不确定的。 m[m.size()]
可能首先发生,也可能发生第二次。如果它首先发生,那么您会看到收到的结果。如果它发生在第二个,那么你会得到你期望的输出。
如果你想
0 0
1 1
2 2
然后,您需要保证自己订购。您可以使用它map::insert()
来做到这一点:
m.insert(m.size(), m.size());
从 C++17 开始,情况不再如此。 标准改为:
赋值运算符 (=) 和复合赋值运算符都从右到左分组。都需要一个可修改的左值作为左操作数;它们的结果是一个引用左操作数的左值。如果左操作数是位域,则所有情况下的结果都是位域。在所有情况下,赋值都在左右操作数的值计算之后和赋值表达式的值计算之前进行排序。右操作数在左操作数之前排序。对于不确定顺序的函数调用,复合赋值的操作是单次求值。
它现在保证= m.size()
发生在之前m[m.size()]
,并且你得到你期望的顺序。
推荐阅读
- javascript - 从具有未知嵌套数的数组中递归过滤对象
- sql - 我可以为时间戳模式指定 Kafka JDBC 连接器的查询吗?
- google-sheets - 如何根据单独列中的值对表进行条件格式化?
- office-addins - Addin word : 从 base64 文件加载页眉和页脚
- python - 使用一个或多个 docker 容器(来自 withing python)?
- linux - 如何为 execv 添加到 *argv?
- python - python中带有测试用例的数字总和
- ssl - 即使启用了 SSL 代理,Charles 代理的内容也无法读取
- sql - Azure:如何将用户登录映射到数据库?
- php - 你如何在 laravel 的目录中升级?