更改for循环的第三部分后展开for循环结果
unexpend for-loop result after change the third part of for-loop
当我在我的源文件中使用 for-loop
时,我得到了一个未花费的结果。这是最小的源文件(我隐藏了文件头和print_set
的功能):
// the main function
int main(void) {
set<int> test{3, 5};
print_set(test);
for (auto it = test.begin(); it != test.end();) {
auto node = test.extract(it);
++it;
}
print_set(test);
}
然后我用命令编译 运行:
$ g++ --version
g++ (Dedian 8.3.0-6) 8.3.0
... (not very important infomation for this question)
$ g++ -std=c++17 temp.cpp
$ ./a.out
[ 3 5 ]
[ ]
现在一切顺利,但是在我将 for-loop
部分更改为此之后(我将 ++it
替换为 for-loop
头部的第三部分):
for (auto it = test.begin(); it != test.end(); ++it) {
auto node = test.extract(it);
}
现在的结果是:
$ ./a.out
[ 3 5 ]
zsh: segmentation fault (core dumped) ./a.out
Zsh
是我用的 Linux shell 不是很重要的信息。看了一些关于for-loop
如this等的网页,还是不知道为什么?这是一个错误吗?为什么这些不相等并且有两个不同的结果?因为方法extract
?但是为什么第一部分可以运行?
谢谢。
来自std::set<T>::extract()
documentation:
Extracting a node invalidates the iterators to the extracted element.
调用test.extract(it)
后,迭代器it
不再有效。甚至增加它或将它与另一个迭代器进行比较都不是定义的操作。提取后您可以对 it
执行的唯一安全操作是:
- 让它被破坏。
- 为其分配一个有效的迭代器。
任何其他原因都会导致未定义的行为,因此您问题中的两个代码示例都会调用未定义的行为。问为什么一个人做的事情与另一个人不同是一个毫无意义的问题。每次程序 运行 时,它们可能各自做一些不同的事情——包括您希望代码做的事情!
无法解释未定义的行为,尝试这样做几乎总是浪费时间。
要修复代码,您需要复制迭代器,增加原始迭代器,然后提取副本。这正是 post-增量运算符所做的:
for (auto it = test.begin(); it != test.end();) {
auto node = test.extract(it++);
}
在此示例中,it
在 提取发生之前 发生了变异。此示例具有明确定义的行为,并将逐个提取集合中的每个元素。
当我在我的源文件中使用 for-loop
时,我得到了一个未花费的结果。这是最小的源文件(我隐藏了文件头和print_set
的功能):
// the main function
int main(void) {
set<int> test{3, 5};
print_set(test);
for (auto it = test.begin(); it != test.end();) {
auto node = test.extract(it);
++it;
}
print_set(test);
}
然后我用命令编译 运行:
$ g++ --version
g++ (Dedian 8.3.0-6) 8.3.0
... (not very important infomation for this question)
$ g++ -std=c++17 temp.cpp
$ ./a.out
[ 3 5 ]
[ ]
现在一切顺利,但是在我将 for-loop
部分更改为此之后(我将 ++it
替换为 for-loop
头部的第三部分):
for (auto it = test.begin(); it != test.end(); ++it) {
auto node = test.extract(it);
}
现在的结果是:
$ ./a.out
[ 3 5 ]
zsh: segmentation fault (core dumped) ./a.out
Zsh
是我用的 Linux shell 不是很重要的信息。看了一些关于for-loop
如this等的网页,还是不知道为什么?这是一个错误吗?为什么这些不相等并且有两个不同的结果?因为方法extract
?但是为什么第一部分可以运行?
谢谢。
来自std::set<T>::extract()
documentation:
Extracting a node invalidates the iterators to the extracted element.
调用test.extract(it)
后,迭代器it
不再有效。甚至增加它或将它与另一个迭代器进行比较都不是定义的操作。提取后您可以对 it
执行的唯一安全操作是:
- 让它被破坏。
- 为其分配一个有效的迭代器。
任何其他原因都会导致未定义的行为,因此您问题中的两个代码示例都会调用未定义的行为。问为什么一个人做的事情与另一个人不同是一个毫无意义的问题。每次程序 运行 时,它们可能各自做一些不同的事情——包括您希望代码做的事情!
无法解释未定义的行为,尝试这样做几乎总是浪费时间。
要修复代码,您需要复制迭代器,增加原始迭代器,然后提取副本。这正是 post-增量运算符所做的:
for (auto it = test.begin(); it != test.end();) {
auto node = test.extract(it++);
}
在此示例中,it
在 提取发生之前 发生了变异。此示例具有明确定义的行为,并将逐个提取集合中的每个元素。