如何有效地将(一些)项目从一个 std::map 移动到另一个?
How to efficiently move (some) items from one std::map to another?
我有两个 std::map<>
对象 a
和 b
并且想从一个对象中移动 (extract
+ insert
) 一些元素(节点)根据某些谓词 p
.
映射到另一个
for (auto i = a.begin(); i != a.end(); ++i)
if (p(*i))
b.insert(a.extract(i))
此代码在 clang 中出现段错误。我认为问题是 i
在其节点从 a.
中提取后的增量
right/only 是否可以通过使用 post 增量来解决此问题?例如:
for (auto i = a.begin(); i != a.end();)
if (p(*i))
b.insert(a.extract(i++))
else
++i;
编辑:我删除了关于 "why this works in gcc?" 的部分,因为我无法在当前设置中重现它。我确信它曾经在某个时间点使用过,但是使用 gcc 9.2.1 我遇到了死锁(而不是段错误)。无论哪种方式,在 extract()
之后递增都不起作用。
I assume the problem is the increment of i after it's node has been extracted from a.
确实如此。提取使提取元素的迭代器无效,i
就是这样的迭代器。通过无效迭代器递增或间接的行为未定义。
Why does this seemingly work in gcc but not in clang?
因为程序的行为是未定义的。
Is the right/only way to fix this with a post-increment?
这是 a 解决此问题的正确方法。这不是一个特别糟糕的方法。如果您不想重复增量,一种方法是使用变量:
for (auto i = a.begin(); i != a.end();) {
auto current = i++;
if (p(*current)) {
// moving is probably unnecessary
b.insert(a.extract(std::move(current)));
}
}
我有两个 std::map<>
对象 a
和 b
并且想从一个对象中移动 (extract
+ insert
) 一些元素(节点)根据某些谓词 p
.
for (auto i = a.begin(); i != a.end(); ++i)
if (p(*i))
b.insert(a.extract(i))
此代码在 clang 中出现段错误。我认为问题是 i
在其节点从 a.
right/only 是否可以通过使用 post 增量来解决此问题?例如:
for (auto i = a.begin(); i != a.end();)
if (p(*i))
b.insert(a.extract(i++))
else
++i;
编辑:我删除了关于 "why this works in gcc?" 的部分,因为我无法在当前设置中重现它。我确信它曾经在某个时间点使用过,但是使用 gcc 9.2.1 我遇到了死锁(而不是段错误)。无论哪种方式,在 extract()
之后递增都不起作用。
I assume the problem is the increment of i after it's node has been extracted from a.
确实如此。提取使提取元素的迭代器无效,i
就是这样的迭代器。通过无效迭代器递增或间接的行为未定义。
Why does this seemingly work in gcc but not in clang?
因为程序的行为是未定义的。
Is the right/only way to fix this with a post-increment?
这是 a 解决此问题的正确方法。这不是一个特别糟糕的方法。如果您不想重复增量,一种方法是使用变量:
for (auto i = a.begin(); i != a.end();) {
auto current = i++;
if (p(*current)) {
// moving is probably unnecessary
b.insert(a.extract(std::move(current)));
}
}