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
感觉这一定是未定义的行为。那是对的吗?如果是这样,标准的哪一部分是这样说的?
这都是参考 C++17。
编辑 2** 我收回我最初所说的话,我只是通过部分 c++ 标准和评论。在 §26.2.6 中,关联容器上下文中 a.erase(r) 的标准状态是 "If no such element exists, returns a.end()." 但是,该标准还声明 "r denotes a valid dereferenceable iterator to a"
由于 m2.begin() 不是这种情况,这不符合标准,因此是未定义的行为。
This feels like it must be undefined behaviour. Is that correct?
是的。
If so, which part of the standard says so?
标准在 [associative.reqmts] 注释 8 中消除了这一点愚蠢。我是 citing n4659 因为这是我的 link 接近 C++17。目前 C++20 仍然是一个移动目标。
深入 [tab:container.assoc.req] 我们发现三个 erase
采用迭代器的重载,
a.erase(q)
a.erase(r)
a.erase(q1, q2)
其中 a.erase(r)
是提问者感兴趣的。
table 仅说明程序运行时会发生什么;但是 table 的序言指出
q
denotes a valid dereferenceable constant iterator to a
, r
denotes a valid dereferenceable iterator to a
, [q1
, q2
) denotes a valid range of constant iterators in a
也就是说,如果迭代器r
不是来自map
a
、a
的end
迭代器,或者已经失效或者否则会变得不可引用,合同就被打破,结果也没有定义。
我包括 q
、q1
和 q2
以表明规则对于常量迭代器和迭代器范围是相同的。
拿这个 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
感觉这一定是未定义的行为。那是对的吗?如果是这样,标准的哪一部分是这样说的?
这都是参考 C++17。
编辑 2** 我收回我最初所说的话,我只是通过部分 c++ 标准和评论。在 §26.2.6 中,关联容器上下文中 a.erase(r) 的标准状态是 "If no such element exists, returns a.end()." 但是,该标准还声明 "r denotes a valid dereferenceable iterator to a"
由于 m2.begin() 不是这种情况,这不符合标准,因此是未定义的行为。
This feels like it must be undefined behaviour. Is that correct?
是的。
If so, which part of the standard says so?
标准在 [associative.reqmts] 注释 8 中消除了这一点愚蠢。我是 citing n4659 因为这是我的 link 接近 C++17。目前 C++20 仍然是一个移动目标。
深入 [tab:container.assoc.req] 我们发现三个 erase
采用迭代器的重载,
a.erase(q)
a.erase(r)
a.erase(q1, q2)
其中 a.erase(r)
是提问者感兴趣的。
table 仅说明程序运行时会发生什么;但是 table 的序言指出
q
denotes a valid dereferenceable constant iterator toa
,r
denotes a valid dereferenceable iterator toa
, [q1
,q2
) denotes a valid range of constant iterators ina
也就是说,如果迭代器r
不是来自map
a
、a
的end
迭代器,或者已经失效或者否则会变得不可引用,合同就被打破,结果也没有定义。
我包括 q
、q1
和 q2
以表明规则对于常量迭代器和迭代器范围是相同的。