【发布时间】:2020-03-09 09:03:54
【问题描述】:
我有两个std::map<> 对象a 和b,并且想根据一些谓词p 将一些元素(节点)从一个映射移动(extract + insert)到另一个映射。
for (auto i = a.begin(); i != a.end(); ++i)
if (p(*i))
b.insert(a.extract(i))
此代码在 clang 中出现段错误。我认为问题是i 在其节点从 a 中提取后的增量。
是通过使用后增量来解决此问题的正确/唯一方法吗?例如:
for (auto i = a.begin(); i != a.end();)
if (p(*i))
b.insert(a.extract(i++))
else
++i;
编辑:我删除了关于“为什么这在 gcc 中有效?”的部分,因为我无法在我当前的设置中重现它。我确信它曾经在某个时间点使用过,但是使用 gcc 9.2.1 我遇到了死锁(而不是段错误)。无论哪种方式,在extract() 之后递增都不起作用。
【问题讨论】:
-
@Eljay 在我看来,C++17 中的新映射“node handle”拼接 API 已经足够专业化,足以证明自己的问题。我希望这不会因为重复而关闭。
-
Deleting elements from std::set while iterating 的可能重复项。
std::set和std::map非常相似,据我所知,extract与erase具有相同的失效含义。 -
你用的是什么版本的clang和gcc?对我来说,使用 clang 8.0 和 gcc 7.4 都会导致段错误。
-
我很惊讶这段代码可以在任何编译器中运行。您没有处理由 extract 引起的失效