对于我正在使用的任何STL容器,如果我使用迭代器的默认构造函数声明一个迭代器(此特定容器类型),迭代器将初始化为什么?
例如,我有:
std::list<void*> address_list;
std::list<void*>::iterator iter;
它将被初始化为什么?
答案 0 :(得分:52)
按照惯例,容器的“NULL迭代器”用于表示没有结果,它与container.end()
的结果相等。
std::vector<X>::iterator iter = std::find(my_vec.begin(), my_vec.end(), x);
if (iter == my_vec.end()) {
//no result found; iter points to "nothing"
}
但是,由于默认构造的容器迭代器不与任何特定容器相关联,因此它没有任何好处。因此它只是一个未初始化的变量,唯一合法的操作就是为它分配一个有效的迭代器。
std::vector<X>::iterator iter; //no particular value
iter = some_vector.begin(); //iter is now usable
对于其他类型的迭代器,这可能不是真的。例如,在istream_iterator
的情况下,默认构造的迭代器表示(比较等于)已达到输入流的EOF的istream_iterator
。
答案 1 :(得分:22)
默认构造函数将迭代器初始化为奇异值:
迭代器也可以具有与任何序列无关的奇异值。 [示例:在声明未初始化的指针x之后(与int * x;一样), 必须始终假定x具有指针的奇异值。 - 末端的例子] 大多数表达式的结果未定义为奇异值 [24.2.1§5]
答案 2 :(得分:11)
迭代器未初始化,就像int x;
声明一个未初始化的整数一样。它没有正确定义的值。
答案 3 :(得分:0)
最新答案。
直到并包括 C ++ 11 :默认和值初始化的迭代器可能包含奇异值。从技术上讲,它不能被比较或取消引用。参见[iterator.requirements.general]/p5。
但是,按照惯例,STL实现用于将此类迭代器初始化为 past-the-end 迭代器。
从 C ++ 14 开始:一个值初始化的 forward 迭代器比较等于一个 past-the-end 迭代器。参见[iterators.forward.iterators]/p2:
...值初始化的迭代器可以进行比较,并且应与相同类型的其他值初始化的迭代器进行比较。 [注意:值初始化的迭代器的行为就像它们引用了同一空序列的末尾一样。 -注释]
因此:
std::list<void*>::iterator iter {};
应该作为过去的迭代器。
std::list<void*>::iterator iter;
是危险的,因为iter
仅在具有非平凡的默认构造函数的情况下才会被初始化。尽管对于std::list
可能是这种情况,所以也应该有效。