【发布时间】:2020-07-06 10:59:45
【问题描述】:
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> numbers;
numbers.insert(1);
auto numbers_find = numbers.find(1);
auto numbers_end = numbers.end();
cout<<*numbers_find<<endl;
cout<<*numbers_end<<endl;
cout<<(numbers_find==numbers_end?"true":"false")<<endl;
return 0;
}
在这种情况下,输出将是
1
1
false
据我所知,迭代器基本上是指针,但仅适用于 STL 集合的元素。 所以我的问题是——当我们比较两个迭代器时,到底在比较什么,我认为这是指针指向的某种地址的等价物。但是,根据指针逻辑,如果两个迭代器指向同一个元素,那么它们相等就有意义。
int a = 5;
int *ptr1 = &a;
int *ptr2 = &a;
cout<<((ptr1==ptr2)?"true":"false")<<endl;
输出
true
附: 链接到上面的代码示例https://repl.it/@VanyaRyanichev/FrillyPapayawhipMonitor#main.cpp
【问题讨论】:
-
取消引用结束迭代器是否与您的问题相关?你不能那样做。
-
*numbers_end是 UB。就像int *ptr2 = &a + 1; cout << *ptr2; /* how come it prints 1 but ptr1 == ptr2 is false? */ -
@VanyaRyanichev 它指向第一个元素的末尾,即它指向不存在的第二个元素。由于没有第二个元素,因此取消引用它是 UB
-
进入实现细节(可能会有所不同),
std::set是一个二叉搜索树。std::set::iterator是一个内部保存指向树节点的指针的类。当您比较迭代器时,您会比较这些指针。std::set::end()指向某个哨兵节点并且不能被取消引用,因为该哨兵节点不是“完整”节点并且不保存任何用户数据,而只有left、right和parent指针。跨度> -
@Vanya Ryanichev 请检查此en.cppreference.com/w/cpp/container/set/end。您可以直观地观察结束指针。