对于我正在使用的任何STL容器,如果我使用迭代器的默认构造函数声明一个(此特定容器类型的)迭代器,则该迭代器将初始化为什么?
例如,我有:
std::list<void*> address_list;
std::list<void*>::iterator iter;
将初始化什么?
对于我正在使用的任何STL容器,如果我使用迭代器的默认构造函数声明一个(此特定容器类型的)迭代器,则该迭代器将初始化为什么?
例如,我有:
std::list<void*> address_list;
std::list<void*>::iterator iter;
将初始化什么?
Answers:
按照惯例,容器的“ 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
,默认构造的迭代器表示(比较等于)istream_iterator
已达到输入流的EOF的。
默认的构造函数将迭代器初始化为一个奇异值:
迭代器还可以具有不与任何序列关联的奇异值。 [示例:在声明未初始化的指针
x
(如int* x;
)之后,x
必须始终假定其具有指针的奇异值。—最终示例]
对于奇异值,大多数表达式的结果均未定义 [24.2.1§5]
<sigh>
可理解的语音是什么意思?
NULL
对于指针而言)?我以为T*
是有效的类型std::vector<T>::iterator
?(以前的Dinkumware实现曾经这样做。)如果是这样,那么std::vector<T>::iterator it;
肯定不会初始化it
为特殊值std::vector<T>::iterator it = std::vector<T>::iterator();
。
迭代器未初始化,就像int x;
声明未初始化的整数一样。它没有正确定义的值。
NULL
是指针可能具有的值。尽管所有指针都是迭代器,但并非所有迭代器都是指针。
更新的答案。
直到C ++ 11(包括C ++ 11):默认和值初始化的迭代器可能包含一个奇异值。从技术上讲,它不能被比较或取消引用。参见[iterator.requirements.general] / p5。
但是,按照约定,STL实现用于将此类迭代器初始化为过去的迭代器。
从C ++ 14开始:值初始化的正向迭代器比较等于过去的迭代器。参见[iterators.forward.iterators] / p2:
...值初始化的迭代器可以进行比较,并且应与相同类型的其他值初始化的迭代器进行比较。[注意:值初始化的迭代器的行为就像它们引用了同一空序列的末尾一样。 —尾注]
因此:
std::list<void*>::iterator iter {};
应该作为过去的迭代器。
std::list<void*>::iterator iter;
这是危险的,因为iter
只有在具有非平凡的默认构造函数的情况下才会进行初始化。尽管std::list
可能是这种情况,所以也应该起作用。
std::list<void*>::iterator iter;
是一个定义。尽管所有定义都是声明,但不是定义的声明将是:extern std::list<void*>::iterator iter;
。