gpt4 book ai didi

c++ - 在 C++17 中迭代时从 std::set 中删除元素

转载 作者:可可西里 更新时间:2023-11-01 18:23:21 24 4
gpt4 key购买 nike

我读过 this SO post , 和 this one too关于在迭代期间从 std::set 中删除元素。但是,C++17 中似乎存在更简单的解决方案:

#include <set>
#include <iostream>
int main(int argc,char **argv)
{
std::set<int> s;

s.insert(4);
s.insert(300);
s.insert(25);
s.insert(-8);

for (auto it:s)
{
if (it == -8)
{
s.erase(it);
}
}
std::cout << "s = {";
for (auto it:s)
{
std::cout << it << " ";
}
std::cout << "}\n";
return 0;
}

当我编译并运行它时,一切都很完美:

$ g++ -o main main.cpp
$ ./main
s = {4 25 300 }

像这样删除元素有什么注意事项吗?谢谢。

最佳答案

根据 C++17 标准:

9.5.4 The range-based for statement [stmt.ranged]

1 The range-based for statement

for ( for-range-declaration : for-range-initializer ) statement

is equivalent to

{
auto &&__range = for-range-initializer ;
auto __begin = begin-expr ;
auto __end = end-expr ;
for ( ; __begin != __end; ++__begin )
{
for-range-declaration = *__begin;
statement
}
}

所以,您的代码无效,因为您删除了迭代器当前指向的元素(std::set 只能有一个相同的值键!),因此迭代器失效并之后递增,这是未定义的行为。

请注意,您可以从集合中删除 另一个 元素,如 std::set (以及 std::mapstd::list) 只有删除的迭代器无效,而所有其他迭代器仍然有效。

如果您打算删除容器的当前元素(包括std::vector,因为erase 返回一个新的、有效的迭代器),您需要回退到经典循环,如 answer 中所示引用问题;我个人喜欢以下的单行变体:

    iter = /*some condition*/ ? container.erase(iter) : std::next(iter);

关于c++ - 在 C++17 中迭代时从 std::set 中删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51744166/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com