C++ 映射擦除-将迭代器传递到错误的映射
以这段C++代码为例:C++ 映射擦除-将迭代器传递到错误的映射,c++,language-lawyer,undefined-behavior,stdmap,C++,Language Lawyer,Undefined Behavior,Stdmap,以这段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(); } #包括 int main(){ std::map m1; m1[1]=2; std::map m2; m2[
#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();
}
#包括
int main(){
std::map m1;
m1[1]=2;
std::map m2;
m2[3]=4;
m1.擦除(m2.开始());
返回m2.size();
}
在锁销上:
这感觉一定是未定义的行为。对吗?如果是这样,标准的哪一部分是这样说的?这都是参考C++17 <>编辑2 **我收回我原先说的,我只是通过部分C++标准和评论。在§26.2.6中,关联容器上下文中a.erase(r)的标准状态为“如果不存在此类元素,则返回a.end()”。然而,该标准还规定“r表示对a的有效可解引用迭代器” 由于m2.begin()不是这种情况,因此不符合标准,因此行为未定义 这感觉一定是未定义的行为。对吗 对 如果是,标准的哪一部分这么说 标准在[associative.reqmts]注释8中消除了这一愚蠢之处。我之所以如此,是因为我有一个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
来说明常量迭代器和迭代器范围的规则是相同的。它应该给出未定义的行为。因为在m1.erase(m2.begin())
中,m2.begin()
指向一个对m1
无效的位置。您找到了正确的东西,但在表前的注释中,它说q表示a的有效可解引用常量迭代器,r表示a的有效可解引用迭代器,在这种情况下,我们希望a.erase(r)
从表中。请注意,链接是到标准的较新版本。@user4581301啊,很好的回答。我一定是在文字中迷失了方向。我收回了我的收回。这是未定义的行为!更新答案,你将获得我的向上投票权。旁注:因为在草稿之间章节号经常变化(更不用说官方发布),在这种情况下,更喜欢使用区段标签[Assisial.ReqMTS],所以五年后的人有更好的机会找到C++ 24中的正确部分或其他什么。