在迭代期间从 std::set 中删除元素:实现影响
在删除元素时迭代集合可能会带来挑战,因为操作可能会使迭代器无效。在这种情况下,问题就出现了:这种行为是由 C 标准定义的还是特定于实现的?
实现依赖
根据 C 标准(23.1 .2.8),向集合中插入元素不应影响迭代器或对容器的引用,而擦除元素仅应使迭代器和对已删除元素的引用。然而,在擦除操作期间迭代器的行为并未明确指定,使其对特定于实现的决策开放。
GCC 实现
在提供的示例代码中,使用Ubuntu 10.04 上的 GCC 4.3.3 在迭代期间从集合中删除元素不会使迭代器失效。这表明 GCC 的实现遵循更宽松的方法,允许在擦除后继续使用迭代器。
符合解决方案
为了确保标准一致性,采用不同的方法是必须的。一种常见的解决方案是在擦除元素之前创建迭代器的副本:
for (auto it = numbers.begin(); it != numbers.end(); ) { if (*it % 2 == 0) { numbers.erase(it++); } else { ++it; } }
在这种情况下,后缀增量(it)将旧位置传递给erase()函数,同时跳转到下一个元素。此处首选后缀增量,因为它避免了前缀增量可能出现的潜在双增量问题(当条件为 false 时)。
C 11 Update
With C 11 的出现,提供了更优雅的解决方案。现在,erase() 函数返回一个迭代器,指向最后一个删除的元素后面的元素(如果最后一个元素被删除,则返回 set::end)。这允许更简洁的实现:
for (auto it = numbers.begin(); it != numbers.end(); ) { if (*it % 2 == 0) { it = numbers.erase(it); } else { ++it; } }
以上是在迭代期间从'std::set”中删除元素是 C 中定义的行为还是特定于实现的行为?的详细内容。更多信息请关注PHP中文网其他相关文章!