std::map 擦除 - 将迭代器传递给错误的映射
std::map erase - pass iterator to wrong map
拿这个C++片段:
#include <map>
int main() {
std::map<int, int> m1;
m1[1] = 2;
std::map<int, int> m2;
m2[3] = 4;
m1.erase(m2.begin());
return m2.size();
}
在神霹雳上:https://godbolt.org/z/mJBszn
这感觉它一定是未定义的行为。这是对的吗?如果是这样,标准的哪一部分是这样说的?
这感觉它一定是未定义的行为。这是对的吗?
是的。
如果是这样,标准的哪一部分是这样说的?
该标准在[associaciative.reqmts]注释8中打下了这种愚蠢之处。我引用 n4659 是因为这是我链接到并接近 C++17 的内容。此时,C++20仍然是一个移动目标。
深入研究[tab:container.assoc.req],我们发现三个erase
重载需要迭代器,
a.erase(q)
a.erase(r)
a.erase(q1, q2)
其中a.erase(r)
是提问者感兴趣的一个。
该表仅说明程序运行时会发生什么;但是该表的序言指出
q
表示a
的有效可取消引用常量迭代器,r
表示a
的有效可取消引用迭代器,[q1
,q2
(表示a
常量迭代器的有效范围
换句话说,如果迭代器r
不是来自map
a
,a
的end
迭代器,或者已被无效或以其他方式被渲染为不可取消引用,则合约被破坏,结果未定义。
我包括q
、q1
和q2
,以表明常量迭代器和迭代器范围的规则是相同的。
这都是参考C++17。
编辑 2** 我收回了我最初所说的内容,我只是从 c++ 标准的一部分和评论中穿行。在 §26.2.6 中,a.erase(r( 在关联容器上下文中的标准状态是"如果不存在这样的元素,则返回 a.end((。但是,该标准还指出"r 表示对 a 的有效可取消引用迭代器">
由于 m2.begin(( 不是这种情况,因此不符合标准,因此行为未定义。
相关文章:
- C++映射分割错误(核心转储)
- 错误处理.将系统错误代码映射到泛型
- 删除映射和分割错误中的一个过去结束元素
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- OpenGL 4.3 错误地将第 4 个纹理坐标映射到与第 3 个纹理坐标相同的位置
- 线程时访问静态映射时出现隔离错误
- C++ 将元素分配给映射值时访问错误
- C++映射容器 erase() 分段错误
- 为C++中的无序映射获取给定输入键的错误值
- std::映射服装比较函数和函数/lambda错误
- 自定义哈希表实现-将字符串映射到整数时出现内存错误
- 使用无序映射进行错误索引
- std::映射导致插入时出现C2664错误
- 与映射和unordered_map相关的编译错误:"attempting to reference a deleted function"
- 在共享内存中插入映射映射时出现编译器错误
- 访问range_expression中的嵌套元素会返回不完整的映射(段错误)
- std::map 擦除 - 将迭代器传递给错误的映射
- 解析序列/映射节点时出现无效的 yaml 节点错误
- 为什么 du -sh 输出错误大小的内存映射文件
- C ++尝试访问映射中的元素会给我一个不匹配的函数调用错误