以下程序是否会调用未定义的行为?
#include <iostream>
#include <iterator>
int main(int argc, char* argv[])
{
for (auto it = std::istream_iterator<std::string>(std::cin);
it != std::istream_iterator<std::string>();
++it)
{
std::cout << *it << " ";
}
return 0;
}
此4 year old question表示无法对其进行比较:
迭代器也可以具有与之无关的奇异值 任何容器。 [例子:宣布未初始化后 指针x(与int * x;一样),x必须始终假定为a 指针的奇异值。 ]大多数表达的结果是 未定义的奇异值;唯一的例外是任务 具有奇异值的迭代器的非奇异值。
但对C ++ 14标准说的另一个答案是:
但是,可以比较值初始化的迭代器并进行比较 等于相同类型的其他值初始化迭代器。
答案 0 :(得分:13)
您正在混淆两个不同的问题。
istream_iterator
是一个输入迭代器,而不是前向迭代器,因此引用的C ++ 14更改根本不适用于它。您可以以这种方式比较istream_iterator
,因为它们被明确指定为允许进行此类比较。标准说(§24.6.1[istream.iterator])
始终没有参数
istream_iterator()
的构造函数 构造一个end-of-stream输入迭代器对象,这是唯一的 合法的迭代器用于结束条件。 [...]两个流末端迭代器总是相等的。流末尾 迭代器不等于非流末端迭代器。二 非结束流迭代器在构造时是相等的 相同的流。
对于前向迭代器(通常还包括双向和随机访问),值初始化迭代器在C++14中相互比较。如果您的标准库实现它,那么您可以比较两个值初始化的迭代器。这允许您创建没有底层容器的空范围。但是,仍然不允许将非奇异迭代器与值初始化迭代器进行比较。即使在C ++ 14中,以下代码也有未定义的行为:
std::list<int> l;
if(l.begin() == std::list<int>::iterator())
foo();
else
bar();