什么是“std::set<int,int>::iterator”?

What is a `std::set<int,int>::iterator`?

提问人:Anubis 提问时间:10/28/2019 更新时间:10/28/2019 访问量:545

问:

我在网上遇到了以下看起来很奇怪的代码片段(简化)。

#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;
}

我刚刚验证了这个编译和运行。(执行时打印)1

我不明白迭代器类型定义。

定义为无效,因为类型声明的第二个可选模板参数必须是支持 的比较器。mysetset<int, int> myset;setbool operator()(int& const lhs, int& const rhs) const

但是为什么迭代器定义不会失败呢?它的底层容器不应该与目标容器具有相同的类型吗?

C++ 迭代器 14 C+ +-标准库

评论

1赞 273K 10/28/2019
当您访问迭代器类型时,不会使用第二个模板参数,因此没有错误。

答:

4赞 StoryTeller - Unslander Monica 10/28/2019 #1

您是正确的,第二个模板参数无效。这违反了容器的前提条件,使整个事物具有未定义的行为。但总的来说,这里有几件事需要解开,所以我们可以对此进行一些推理。关键点如下:

  1. 实例化必须以某种方式使用无效的模板参数来触发失败。它必须在与类定义一起实例化的地方使用。并非总是实例化整个类。一个著名的例子是成员函数。这些仅在实际调用时根据需要实例化。

  2. 键入的值可以是别名。此外,它可能是多个不同集专用化共享的类型的别名。在这种情况下,仅依赖于第一个模板参数并非不可想象。这意味着您创建的类型可能与另一个 .iterator::iteratorbegin

但归根结底,这是一个格式错误的程序。混合来自不同容器的迭代器本身是未定义的,但在此之前还有一个前提条件冲突。总而言之,这不是值得强调的事情,因为除了智力练习之外,这样的代码不应该出现在任何地方。