什么是 std::set<int,int>::iterator`?
What is a `std::set<int,int>::iterator`?
我在网上看到了以下看起来很奇怪的代码片段(已简化)。
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> myset{1, 2, 3, 4, 5};
set<int, int>::iterator it = myset.begin();
cout << *it << endl;
return 0;
}
我刚刚验证了 this compiles and runs。 (执行时打印 1
)
我不明白迭代器类型定义。
将 myset
定义为 set<int, int> myset;
无效,因为 set
类型声明的第二个可选模板参数必须是支持 bool operator()(int& const lhs, int& const rhs) const
.
的比较器
但是为什么迭代器定义不会失败呢?它的底层容器不应该与目标容器具有相同的类型吗?
你说得对,第二个模板参数无效。这违反了容器的先决条件,使整个事物具有未定义的行为。但总的来说,这里有几件事情需要解包,所以我们可以对其进行一些推理。关键点是这些:
实例化必须使用无效的模板参数以某种方式触发失败。而且它必须在与 class 定义一起实例化的地方使用。并非总是实例化整个 class。一个著名的例子是成员函数bodies。这些仅在实际调用时根据需要实例化。
iterator
类型可能是别名。此外,它可能是几个不同的集特化共享的类型的别名。在这种情况下, ::iterator
仅取决于第一个模板参数并不是不可想象的。这意味着您创建的类型可能与其他 begin
.
返回的类型相同
但归根结底,这是一个格式错误的程序。混合来自不同容器的迭代器本身是未定义的,但在此之前您还有一个先决条件违规。总而言之,这不是什么值得强调的事情,因为除了在智力练习中,这样的代码不应该出现在任何地方。
我在网上看到了以下看起来很奇怪的代码片段(已简化)。
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> myset{1, 2, 3, 4, 5};
set<int, int>::iterator it = myset.begin();
cout << *it << endl;
return 0;
}
我刚刚验证了 this compiles and runs。 (执行时打印 1
)
我不明白迭代器类型定义。
将 myset
定义为 set<int, int> myset;
无效,因为 set
类型声明的第二个可选模板参数必须是支持 bool operator()(int& const lhs, int& const rhs) const
.
但是为什么迭代器定义不会失败呢?它的底层容器不应该与目标容器具有相同的类型吗?
你说得对,第二个模板参数无效。这违反了容器的先决条件,使整个事物具有未定义的行为。但总的来说,这里有几件事情需要解包,所以我们可以对其进行一些推理。关键点是这些:
实例化必须使用无效的模板参数以某种方式触发失败。而且它必须在与 class 定义一起实例化的地方使用。并非总是实例化整个 class。一个著名的例子是成员函数bodies。这些仅在实际调用时根据需要实例化。
iterator
类型可能是别名。此外,它可能是几个不同的集特化共享的类型的别名。在这种情况下,::iterator
仅取决于第一个模板参数并不是不可想象的。这意味着您创建的类型可能与其他begin
. 返回的类型相同
但归根结底,这是一个格式错误的程序。混合来自不同容器的迭代器本身是未定义的,但在此之前您还有一个先决条件违规。总而言之,这不是什么值得强调的事情,因为除了在智力练习中,这样的代码不应该出现在任何地方。