是否可以与值初始化的迭代器进行比较?

时间:2014-10-07 17:36:55

标签: c++ c++11

以下程序是否会调用未定义的行为?

#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标准说的另一个答案是:

  

但是,可以比较值初始化的迭代器并进行比较   等于相同类型的其他值初始化迭代器。

1 个答案:

答案 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();